关闭时未收到 NSNotificationCenter 通知

Posted

技术标签:

【中文标题】关闭时未收到 NSNotificationCenter 通知【英文标题】:NSNotificationCenter Notification Not Being Received When Posted in a Closure 【发布时间】: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) ,但这似乎不起作用。这是否在主队列上正确运行? 【参考方案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 仅在类不相交时使用。感谢您的澄清和回答。 与其说是方向,不如说是建议。

以上是关于关闭时未收到 NSNotificationCenter 通知的主要内容,如果未能解决你的问题,请参考以下文章

应用关闭或被杀时未收到 Android FCM 通知

关闭 android 应用程序时未收到 Azure 推送通知

关闭应用程序时未收到 Xamarin Forms Android 推送通知

IBM Worklight 5.0.6.1 - 关闭电话/应用程序时未收到推送通知

系统刚启动时未收到 FCM 通知

应用程序处于前台时未收到 Firebase 推送通知