ios - 尝试快速实现发布者/订阅者

标签 ios xcode swift publish-subscribe

我实际上正在尝试在我的 Swift 项目中实现发布/订阅模式,我有几个 Agents(Singleton)在状态改变时执行任务他们应该通知所有之前订阅的听众。

我在调整我的协议(protocol)时遇到错误,它可能应该符合 Equatable 协议(protocol),但我看不到以哪种方式(声明 protocol AvailableChatListener: Equatable 没有解决任何问题).

我知道我可以使用 Apple 的 NSNotificationCenter(很好地指出 here ),但它不是完全适合我的要求的解决方案。

这里是代码:

AvailableChatListener.swift

protocol AvailableChatListener {
    func onAvailableChatChange()
}

AvailableChatAgent.swift

class AvailableChatAgent {
  // MARK: - Singleton

  class var sharedInstance: AvailableChatAgent {
    struct Singleton {
      static let instance = AvailableChatAgent()
    }
    return Singleton.instance
  }

  // MARK: - Listeners

  private var availableChatListeners = [AvailableChatListener]()

  // MARK: - Public Properties

  // current Chats
  var currentChats = [Chat]()   {
    didSet  {
      statusChanged()
    }
  }

  func startObserving()   {
    // ...
    // perform tasks and change currentChats
    // ...
  }

  func stopObserving()    {
    // ...
    // stop tasks
    // ...
  }

  func statusChanged()    {

    // notify listeners
    for receiver in availableChatListeners {
      receiver.onAvailableChatChange()
    }
  }

  // ERROR #1
  func subscribeListener(listener: AvailableChatListener)    {
    availableChatListeners.append(listener)
  }

  // ERROR #1
  func unsubscribeListener(listener: AvailableChatListener)  {

    // ERROR #2
    if let index = availableChatListeners.indexOf(listener) {
      availableChatListeners.removeAtIndex(availableChatListeners.indexOf(listener)!)

      if availableChatListeners.count == 0 {
        self.stopObserving()
      }
    }
  }
}

在这里我使用了这个逻辑(例如在 TableViewController 中)

ChatListTableViewController.swift

class ChatListTableViewController: UITableViewController, AvailableChatListener {

  // MARK: - Properties

  var availableChatAgent = AvailableChatAgent.sharedInstance

  // MARK: - ViewDidLoad

  override func viewDidLoad() {
    super.viewDidLoad()

    availableChatAgent.subscribeListener(self)
  }

  // MARK: - Implement AvailableChatListener

  func onAvailableChatChange()    {
    // perform task with the new data, for example update UI
  }
}

提前致谢。

更新 1

我得到的错误:

  1. protocol "AvailableChatListener' 只能用作通用约束,因为它具有 Self 或关联类型要求
  2. 无法将“AvailableChatListener”类型的值转换为期望参数类型“@noescpae(AvailableChatListener) throws -> Bool”

最佳答案

请尝试这种移除监听器的方法,看看它是否有效。我已将对象转换为 NSArray,然后在该数组中查找监听器的索引。我假设如果两个监听器是同一对象而不是任何其他条件,则它们是相等的。

func unsubscribeListener(listener: AvailableChatListener)  {
    let arr = availableChatListeners as NSArray
    let index = arr.indexOfObject(listener)
    if index != NSNotFound {
        availableChatListeners.removeAtIndex(index)
        if availableChatListeners.count == 0 {
            self.stopObserving()
        }
    }
}

你也应该这样声明你的协议(protocol)(添加@objc)

@objc protocol AvailableChatListener  {
    func onAvailableChatChange()
}

关于ios - 尝试快速实现发布者/订阅者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35430344/

相关文章:

objective-c - XCode版本可以在OSX 10.5.8上使用吗?

ios - 更新到 iOS 9 错误 : i386 Unsupported architecture

ios - 如何在 Core Data 中自定义保存?

ios - 当 nscoding writeToFile 正在保存并且用户关闭应用程序时,iOS 会发生什么?

objective-c - NetBeans 无法识别 Makefile.am

c++ - OpenCV 将视频保存到文件

ios - 我的 CollectionViewCell 陷入困惑

ios7 - 快速关闭模态视图 Controller 后的 Popview

ios - 如何检测我的设备是否是 Swift 4 中的 iPhone X?

ios - SwiftR 调用方法回调处理程序