关闭时未收到 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】:
由于First
和Second
之间存在直接关系,因此协议/委托模式是更好的通知方式。使用这种模式会更好,您不必担心注销观察者。 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 应用程序时未收到 Azure 推送通知
关闭应用程序时未收到 Xamarin Forms Android 推送通知