2011-04-14 74 views
36

現在API似乎沒有提供一種方法來檢測是否已經爲特定的NSNotification添加了觀察者。避免添加多個NSNotification觀察者的最佳方法是,除了維護一個標誌以保持跟蹤外,還有什麼?有沒有人已經創建了一個類別來促進這一點?如何避免添加多個NSNotification觀察者?

+0

你可以舉一個這種情況發生的例子,或者爲什麼這會成爲一個問題? – 2011-04-14 06:00:01

回答

64

防止重複觀察者被添加的一種方式是在再次添加目標/選擇器之前顯式調用removeObserver。我想你可以添加此爲一類方法:

@interface NSNotificationCenter (UniqueNotif) 

- (void)addUniqueObserver:(id)observer selector:(SEL)selector name:(NSString *)name object:(id)object { 

     [[NSNotificationCenter defaultCenter] removeObserver:observer name:name object:object]; 
     [[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:name object:object]; 

} 

@end 

這假定你將只一個獨特的觀察者添加到每個目標的任何通知的名稱,因爲它會刪除任何現有的觀察員該通知的名字。

+1

你在這裏以非常有趣,非標準的方式使用「觀察者」和「目標」。 'addObserver ...'中的「觀察者」指示發佈通知時將收到消息的對象,而不是指定構成該消息的方法。通知中沒有「目標」的概念。你稱之爲「目標」的東西在文檔中被稱爲「觀察者」。 – 2011-04-14 08:05:45

+2

目標變量指示運行時應該在何處查找對象。我將arg名稱目標更改爲觀察者以消除任何潛在的混淆。 – futureelite7 2011-04-14 09:04:59

+0

雖然我的「你無法回答」可能是太過文字(一個對象無法檢測到它是觀察者),但這個答案充其量只是很差的做法。對於OP來說,更好的建議是使用除用於此用例的發佈和觀察通知之外的其他實現。如果一個通知只打算讓一個觀察者使用,那麼使用一個委託和協議不僅可以強制執行,而且可以在對象和它的委託之間的關係中明確表示。 – XJones 2016-02-27 22:55:09

18

斯威夫特3,4:

import Foundation 

extension NotificationCenter { 
    func setObserver(_ observer: AnyObject, selector: Selector, name: NSNotification.Name, object: AnyObject?) { 
     NotificationCenter.default.removeObserver(observer, name: name, object: object) 
     NotificationCenter.default.addObserver(observer, selector: selector, name: name, object: object) 
    } 
} 

斯威夫特2:

import Foundation 

extension NSNotificationCenter { 
    func setObserver(observer: AnyObject, selector: Selector, name: String?, object: AnyObject?) { 
     NSNotificationCenter.defaultCenter().removeObserver(observer, name: name, object: object) 
     NSNotificationCenter.defaultCenter().addObserver(observer, selector: selector, name: name, object: object) 
    } 
} 
+0

你給我添加觀察者的例子在swift 3.0中使用這個擴展 – 2018-01-08 06:52:24

1

的Upvoted答案與extension NotificationCenter { ... }並沒有爲我工作,因爲我的應用程序中創建每次發佈通知時,都會有一個viewController的新實例(它有一個通知觀察者),所以刪除一個一個viewController的新實例的觀察者顯然不工作。 擁有Notification Observers的viewController的先前實例正在被調用。

下面的內容適用於我,因爲視圖一消失就立即刪除通知觀察者。

// Notification observer added 

override func viewWillAppear(_ animated: Bool) { 

    NotificationCenter.default.addObserver(self, selector: #selector(self.someFunc(notification:)), name: Notification.Name("myNotification"), object: nil) 


} 


// Notification observer removed 

override func viewWillDisappear(_ animated: Bool) { 

    NotificationCenter.default.removeObserver(self, name: Notification.Name("myNotification"), object: nil) 


} 
+1

更好的addObserver'viewDidAppear'而不是'viewWillAppear'。 – dimpiax 2017-10-12 11:54:01