在关闭时发布时未收到NSNotificationCenter通知

时间:2016-05-17 16:08:23

标签: swift alamofire nsnotificationcenter nsnotifications

我要完成的是通过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课程中收到发布的通知?

1 个答案:

答案 0 :(得分:4)

由于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")
  }
}