【问题标题】:NSNotificationCenter Notification Not Being Received When Posted in a Closure关闭时未收到 NSNotificationCenter 通知
【发布时间】:2016-05-17 16:08:22
【问题描述】:

我想要完成的是通过NSNotificationCenter 的默认中心发布通知。这是在使用Alamofire 进行网络调用后在闭包块内完成的。我遇到的问题是应该响应已发布通知的类没有收到此类通知。

我的ViewController 只是创建了一个First 对象,它可以让事物移动:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let first = First()
    }
}

我的First 类创建一个Second 类的实例,并将自己作为观察者添加到我的NSNotificationCenter。这是发布通知时似乎无法获得通知的类。

class First : NSObject {
    let second = Second()
    override init(){
        super.init()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(First.gotDownloadNotification(_:)), name: "test", object: nil)
        second.sendRequest()
    }

    // NOT REACHING THIS CODE
    func gotDownloadNotification(notification: NSNotification){
        print("Successfully received download notification from Second")
    }

}

我的Second 类通过我的NetworkService 类进行网络调用,并在请求成功并完成后在闭包中发布通知。

class Second : NSObject {

    func sendRequest(){
        let networkService = NetworkService()
        networkService.downloadFile() { statusCode in
            if let statusCode = statusCode {
                print("Successfully got a status code")
                // Post notification
                NSNotificationCenter.defaultCenter().postNotificationName("test", object: nil)
            }
        }
    }
}

最后,我的 NetworkService 类是使用 Alamofire 进行网络调用并通过闭包从响应中返回状态代码的原因。

class NetworkService : NSObject {

    func downloadFile(completionHandler: (Int?) -> ()){
        Alamofire.download(.GET, "https://www.google.com") { temporaryURL, response in
            let fileManager = NSFileManager.defaultManager()
            let directoryURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
            let pathComponent = response.suggestedFilename

            return directoryURL.URLByAppendingPathComponent(pathComponent!)
        }
            .response { (request, response, _, error) in
                if let error = error {
                    print("File download failed with error: \(error.localizedDescription)")
                    completionHandler(nil)
                } else if let response = response{
                    print("File downloaded successfully")
                    // Pass status code through completionHandler to Second
                    completionHandler(response.statusCode)
                }
        }

    }
}

执行后的输出为:

文件下载成功
成功获取状态码

从这个输出中我知道下载是成功的,Second 从闭包中得到了状态码并在之后发布了一个通知。

我相信我已经尝试解决有关 Stack Overflow 上与未接收通知有关的大多数其他建议,例如在发布通知之前未实例化对象或添加观察者或发布通知的语法。

有谁知道为什么First 类没有收到发布的通知?

【问题讨论】:

  • @LeoDabus 我尝试将NSNotificationCenter.defaultCenter().postNotificationName("test", object: nil) 更改为dispatch_async(dispatch_get_main_queue()) { NSNotificationCenter.defaultCenter().postNotificationName("test", object: nil) },但这似乎不起作用。这是否在主队列上正确运行?

标签: swift alamofire nsnotificationcenter nsnotifications


【解决方案1】:

由于FirstSecond 之间存在直接关系,因此协议/委托模式是更好的通知方式。使用这种模式会更好,您不必担心注销观察者。 NSNotificationCenter 应该只在发送者和接收者之间没有关系的情况下使用。

基本上线程也不重要。

protocol SecondDelegate {
  func gotDownloadNotification()
}

class Second : NSObject {

  var delegate : SecondDelegate?

  init(delegate : SecondDelegate?) {
    self.delegate = delegate
  }

  func sendRequest(){
    let networkService = NetworkService()
    networkService.downloadFile() { statusCode in
      if let statusCode = statusCode {
        print("Successfully got a status code")
        // Post notification
       self.delegate?.gotDownloadNotification()
      }
    }
  }
}

class First : NSObject, SecondDelegate {
  let second : Second

  override init(){
    super.init()
    second = Second(delegate:self)
    second.sendRequest()
  }

  func gotDownloadNotification(){
    print("Successfully received download notification from Second")
  }
}

【讨论】:

  • 这很好用!我不知道 NSNotificationCenter 仅在类不相交时使用。感谢您的澄清和回答。
  • 与其说是方向,不如说是建议。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
相关资源
最近更新 更多