[英]Observer, Notification, Delegate swift ios8
我正在尋找一些建議,以最好地實現我認為可能是觀察者,可能是多播委托的東西,或者也許我將僅使用通知輸入。
我正在創建一個DataManager
類,該類連接到各種數據源並產生一種通用的數據格式。
我們可以從內部核心位置 , 文件播放 , 網絡套接字提供的位置等生成LocationMessage
。
返回的數據類型是具有通用格式的LocationMessage
,如有必要,也可以將其轉換為CLLocation
。
在我當前的“多委托”模型中,如果要獲取位置更新,則必須實現LocationConsumer
協議,該協議定義了
func didUpdateLocation(newLocation: LocationMessage)
{
println("\(__FUNCTION__) \(newLocation)")
}
那你會
//Instantiate a data manager
let dm : DataManager = DataManager()
//Register yourself as a delegate
dm.addLocationDelegate(self)
在內部,當我們獲得新的位置數據時,將稱為:
let closure = {
(delegate : LocationDataConsumer) -> () in
dispatch_async(self.delegateQueue) {
delegate.didUpdateLocation(parsedLocation)
}
}
locationDelegates.map(closure)
其中locationDelegates
是[LocationConsumer]
的數組
因此,首先,這顯然並不真正遵循委托模式,因為您不應擁有多個委托。
但是,我真正喜歡當前方法的地方是,使用協議似乎很干凈,以便將類標識為關心特定數據類型。 但是,我不滿意的是“打破”了標准的委托模式。
通過閱讀,我認為最合適的方法是使用“ 通知模式”,但是,從編碼的角度來看,我認為涉及到更多的維護工作(盡管我可能是錯的)。 使用此委托方法僅實現協議並調用addDelegate
的簡單性在Notifications中丟失了。 我認為我必須為我關心的每個通知都專門注冊-對嗎?
我無法執行以下操作:
class notificaitonClass : LocationNotifiee, WeatherNotifiee {
}
所以我想我的問題是
(希望這不太模糊)
Stackoverflow並不是回答這個問題的最佳論壇,您應該嘗試developers.stackexchange.com 。 但到底,這是我的快速答案。
在Objective C / Swift中,委托具有特定含義,您描述的模式不合適。 將其稱為事件處理程序,將其稱為更改回調,將其稱為多重委托(ala dm.addLocationMultiDelegate(self)
):只是不要通過重載術語“委托”來使人們感到困惑。
您可以控制什么是通知以及何時發送。 您可能有一個DataMangerDidUpdateLocationNotification
,可以將其從任何來源發布到任何接收者。 如果需要跟蹤誰發布了通知,則可以在userInfo
中使用DataMangerSourceKey
。
此外,您可以將其進一步推廣。 您可能具有一組數據管理器更改的DataMangerDidChangeNotification
。 您可能需要一個DataMangerChangeTypeKey
。
例如:
NSNotificationCenter.defaultCenter().addObserverForName(DataMangerDidChangeNotification, object: nil, queue: nil) {
note in
let changeType = note.userInfo![DataMangerChangeTypeKey] as String
if changeType == DataMangerChangeTypeLocation {
…
} else if changeType == DataMangerChangeTypeOther {
…
}
}
我同意@JefferyThomas。 您所做的工作是完全有效的,但是Swift和Objective-C都沒有將多播委托作為標准設計模式的概念。
這並不是說它有什么問題。 擁有符合給定協議的對象數組是完全有效的,就像使用map函數調用該數組中所有對象的閉包一樣。 Voila,即時多播代表。
如果您使用該術語,那么Cocoa / Cocoa Touch程序員(像我一樣)很容易對您感興趣,這僅僅是因為術語“委托”在Cocoa中的含義很窄,並且該含義並不涵蓋多播委托。
在我看來,您已經為多播代表設計了很多“映射”(雙關語意),因此,如果這很適合您的工作,那就去做吧。 您並沒有破壞委托設計模式-您正在實現的是另一種設計模式,該設計模式並未在平台上廣泛使用,但是仍然十分有效和有用。
當我剛開始閱讀您的問題時,我認為“代表是一對一的。通知更適合。” 這是因為,作為典型的Cocoa / Cocoa Touch開發人員,“委托”一詞對我來說具有狹窄的含義-其中不包括多播委托。 但是,在搜索該術語之前,我已經很確定您的意思了,並且我正在考慮符合通用協議和map函數的對象數組。
通知是解決問題的另一種完全有效的方法。 令我驚訝的是,通知和多播委托之間的區別在於誰來工作。 在多播委托中,發送者必須維護一個目標列表(我會毫不猶豫地稱其為委托),並向每個目標發送所需的消息。
在通知中,發件人不知道或不在乎誰在聽。 發送方只是發出信號彈,而負擔是監聽者需要照顧和響應的負擔。 在這方面,KVO與通知類似。
再多考慮一下,我認為map函數不是正確的選擇。 Map旨在獲取一個源數組,對每個元素執行一些變異操作,然后將變異后的元素返回到一個新的數組中。 它創建一個新數組,您將忽略它。
對於您的多播委托設計模式,您不需要將源數組轉換(映射)為目標數組。 您需要讓數組中的每個元素執行一項任務。
最好使用forEach方法。 這條線
locationDelegates.map(closure)
看起來像這樣:
locationDelegates.foreach
{
closure()
}
(我認為我的語法是正確的-最近我主要在Objective-C中工作,而在Swift中變得生銹。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.