2016-05-17 46 views
2

我想完成的是通過NSNotificationCenter的默認中心發佈通知。這是在使用Alamofire進行網絡呼叫後,在關閉塊內完成的。我遇到的問題是,應該對發佈的通知作出響應的類沒有收到此類通知。NSNotificationCenter通知在關閉時不被接收

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

@LeoDabus我試圖改變'NSNotificationCenter.defaultCenter()postNotificationName( 「測試」,對象:無)。''到dispatch_async(dispatch_get_main_queue()){ NSNotificationCenter.defaultCenter()postNotificationName( 「測試」。 ,object:nil) }'然而這似乎並不奏效。這是否正確運行在主隊列上? –

回答

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") 
    } 
} 
+0

這個作品非常漂亮!我不知道'NSNotificationCenter'只能在類不相交時使用。感謝您的澄清和答覆。 –

+1

這比一個方向更重要。 – vadian