2017-04-17 139 views
1

編輯:解決了,請參閱我的解決方案。我仍然很好奇它爲什麼有效,也許你的解決方案可以解釋這一點?Swift 3可選的綁定協議

我使用NotificationCenter發佈通知傳遞一個對象。

我的目標是如果它堅持某個,可選擇拆開notification.object

問題是在測試中,解包被證明不成功,我不知道爲什麼。

的一系列對象(有時是enum,有時struct)誰堅持NotificationsPipelineProtocol和與通知給誰預訂這些通知接收對象一起發送的那些對象。

因此,舉例來說,如果我在的通知管道傳遞ReleaseNote我會有它訂閱協議:

enum ReleaseNote: Float, NotificationsPipelineProtocol { 
    ... 

當我想張貼到NotificationCenter訂閱的所有項目編寫了一個擴展功能到NotificationsPipelineProtocol被稱爲:

// finishing task, wants to post completion 
    ... 
     self.postCompletion() 
    ... 

調用此函數

func postCompletion() { 
     NotificationCenter.default.post(name: self.completionNotificationName, object: self) 
    } 
我已經保證

使用正確此功能可以收到:

@objc private func didReceiveNotificationCompletion(_ notification : Notification) { 

    guard let completedNotification = notification.object as? NotificationsPipelineProtocol else { 
     return 
    } 

但上面的後衛聲明未展開,並因爲return執行綁定可選。

我已經打印notification.object控制檯,並保證它實際上是接收預期的對象。

你可能有任何想法爲什麼它不會解開?

+0

是不是到達.object包裹在NSValue或NSNumber?在運行時檢查屬性類。 –

+0

我給出了結果:'_SwiftValue'當我打印到控制檯 – achi

+0

可能是我需要將它連接到某種NSObject協議?授予通知中心橋接到Objective-C? – achi

回答

1

我已經通過將對象的管道對象的訪問替換爲userInfo來解決它。

我不完全確定這是爲什麼它應該是,但它確實有效。

公示對象

func postCompletion() { 
     NotificationCenter.default.post(name: self.completionNotificationName, object: nil, userInfo: ["pipelineItem": self]) 
    } 

檢索對象

guard let userInfo = notification.userInfo, 
      let completedNotification = userInfo["pipelineItem"] as? NotificationsPipelineProtocol else { 
     return 
    } 
0

不應該有與此工作流程的任何問題,也許你觀察/發錯了對象?

下面是您正在嘗試做的一個示例,您可以在操場上使用它以查看它是否有效。嘗試將代碼移到操場/示例項目中,直到找到失敗點爲止,這是最簡單的情況!

//: Playground - noun: a place where people can play 

import Foundation 
import PlaygroundSupport 

PlaygroundPage.current.needsIndefiniteExecution = true 

protocol NotificationsPipelineProtocol { 

} 

class TestObserver: NotificationsPipelineProtocol { 

    init() { 
     NotificationCenter.default.addObserver(self, 
               selector: #selector(notificationFired(_:)), 
               name: nil, 
               object: self) 
    } 

    dynamic func notificationFired(_ notification: Notification) { 
     guard let object = notification.object as? NotificationsPipelineProtocol else { 
      return 
     } 

     print("success") 
    } 

    func fireNotification() { 
     NotificationCenter.default.post(name: Notification.Name(rawValue: "test"), object: self) 
    } 

} 

let observer = TestObserver() 
observer.fireNotification() 
+0

我同意,不應該有。但是,這是..我會考慮在沙箱中嘗試你的代碼,但你上面看到的是代碼中寫的是什麼,所以我無法想象它會有很多不同的結果 – achi