我要完成的是通过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
课程中收到发布的通知?
答案 0 :(得分:4)
由于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")
}
}