0

我有一個Poster類,它通過NSNotificationCenter發佈通知。我有兩個不同的觀察員:ObserverSuperclassObserverSubclassObserverSuperclassObserverSubclass的超類。我希望每個班級對通知做出不同的迴應。基於塊的NSNotificationCenter觀察子類?

根據NSHipster,我應該使用現代的基於塊的api:addObserverForName:object:queue:usingBlock:

ObserverSubclass的初始化方法中,我需要刪除超類作爲觀察者。因爲我使用的是基於塊的API,所以我需要引用返回值addObserverForName:object:queue:usingBlock: - 一個「作爲觀察者的不透明對象」。所以我寫了下面的代碼:

ObserverSuperclass.h

@property (nonatomic, strong) id observer;

ObserverSuperclass.m

self.observer = [NSNotificationCenter defaultCenter] addObserverForName:@"Help!" object:nil queue:nil usingBlock:^{old block}];

ObserverSubclass.m

[[NSNotificationCenter defaultCenter] removeObserver:self.observer name:@"Help!" object:nil];

self.observer = [NSNotificationCenter defaultCenter] addObserverForName:@"Help!" object:nil queue:nil usingBlock:^{new block}];

這實際上是這樣做的最好方法嗎?我不確定在這裏使用基於塊的API是否有意義。

+1

您可以實現一個返回處理程序塊的方法。然後,您可以簡單地在子類中重寫此方法,或者僅使用基於選擇器的API – Paulw11 2014-10-21 23:02:47

+0

爲什麼需要以觀察者的身份移除超類?你不想讓這個塊執行嗎? – Roberto 2014-10-21 23:12:33

回答

2

這是一種情況,在我看來,你應該使用傳統而不是@selector回調。你的超類可以註冊觀察並實現默認行爲。這個子類然後只需要覆蓋被調用的返回@選擇器。

,你應該實現的方法是:

- (void)addObserver:(id)notificationObserver 
     selector:(SEL)notificationSelector 
      name:(NSString *)notificationName 
     object:(id)notificationSender 

例如,在超:

- (instancetype) init 
{ ... 
    [[NSNotificationCenter defaultCenter] 
      addObserver:self 
       selector:@selector(oberserveThis:) 
        name:@"someEventName" 
       object:nil]; 
} 

- (void)observeThis:(NSNotification*)notification 
{ 
    // ... Do something here ... 
} 

在子類:

- (void)observeThis:(NSNotification*)notification 
{ 
    // ... Do something else here ... 
} 

如果您需要在代碼觀察者要在特定隊列上執行,您始終可以在觀察選擇器中調用dispatch。我認爲,對於你的用例來說,它比使用基於塊的方法要更簡潔的代碼。

+0

這也是我得出的結論。如果我知道我不會繼承,我只會使用基於塊的API。 – rizzes 2014-10-22 19:28:34

0

你的代碼看起來不錯。

你已經映射出來的邏輯強制了你只想要一個觀察者的想法,無論是超類還是子類。你的子類的觀察者刪除並替換超類的觀察者。

讓他們都觀察相同的通知名稱也是有效的。在這種情況下,你需要將一個新的實例變量self.newObserver添加到子類中,併爲該屬性添加一個觀察者。然後這兩個塊會在「幫助!」時被調用。通知已發佈。

你做什麼取決於你想要完成什麼。

當你不再需要它時,你需要移除一個觀察者,否則當觀察者塊處理的對象從它下面釋放時,你會冒風險。 (基於塊的觀察者比基於選擇者的觀察者更少,因爲通知中心會自動保留塊,並且即使添加觀察者的對象被釋放,觀察者塊仍然會運行。必須記得在你的dealloc方法中刪除你的觀察者,或者當你的對象被釋放後,如果你正在觀察的通知類型被再次發佈,你會崩潰。)

+0

當父子樹的高度大於2時,該系統變得有點笨拙。第三類(它是1和2的子類)將具有self.observer,self.newObserver,self.newNewObserver。而不是將它們存儲爲單獨的屬性,請使用數組? – rizzes 2014-10-22 15:52:08

+0

當聽課有多個觀察員時,這會變得特別髒。我應該有多個數組(或一組self.observer [N])嗎? – rizzes 2014-10-22 16:09:29

+0

當然,一個數組會很好。讓基類有一個在init時創建的可變觀察者對象數組。每個需要它自己的觀察者的子類都會創建一個新的觀察者並將其添加到數組中。基類的dealloc方法可以處理所有這些方法。 – 2014-10-22 21:19:57

相關問題