在闭包中发布时未收到 NSNotificationCenter 通知

NSNotificationCenter Notification Not Being Received When Posted in a Closure

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

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

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

我的 First class 创建了一个 Second class 的实例,并将自己添加为我的 NSNotificationCenter 的观察者。这是发通知的时候好像收不到通知的class

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 class 通过我的 NetworkService class 进行网络调用,并在请求成功完成后在闭包中发布通知。

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 class 是使用 Alamofire 和 returns 通过闭包响应的状态代码进行网络调用的原因。

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)
                }
        }

    }
}

执行后的输出为:

File downloaded successfully
Successfully got a status code

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

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

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

由于 FirstSecond 之间存在直接关系,因此 protocol/delegate 模式是更好的通知方式。使用这种模式更好,您不必注意注销观察者。 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")
  }
}