在闭包中发布时未收到 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 中没有收到发布的通知?
由于 First
和 Second
之间存在直接关系,因此 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")
}
}
我想要完成的是通过 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 中没有收到发布的通知?
由于 First
和 Second
之间存在直接关系,因此 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")
}
}