簡體   English   中英

為什么不從NSNotificationCenter:addObserverForName:usingBlock刪除Observer調用

[英]Why doesn't Remove Observer from NSNotificationCenter:addObserverForName:usingBlock get called

我對為什么在以下代碼中從未刪除觀察者感到困惑。 在我的viewDidAppear中,我具有以下內容:

-(void)viewDidAppear:(BOOL)animated{

id gpsObserver = [[NSNotificationCenter defaultCenter] 
                          addObserverForName:FI_NOTES[kNotificationsGPSUpdated] 
                          object:nil 
                          queue:[NSOperationQueue mainQueue] 
                          usingBlock:^(NSNotification *note){

                              NSLog(@"run once, and only once!");

                [[NSNotificationCenter defaultCenter] removeObserver:gpsObserver];

        }];

}

觀察者永遠不會被刪除,並且每次發出通知時都會輸出該語句。 誰能提供任何指導?

當通過addObserverForName:將塊推送到堆棧上時addObserverForName:該方法尚未返回,因此gpsObserver為nil(在ARC下)或垃圾回收/未定義(不在ARC下)。 在外部使用__block聲明變量,這應該可以工作。

__block __weak id gpsObserver;

gpsObserver = [[NSNotificationCenter defaultCenter] 
                          addObserverForName:FI_NOTES[kNotificationsGPSUpdated] 
                          object:nil 
                          queue:[NSOperationQueue mainQueue] 
                          usingBlock:^(NSNotification *note){

                              NSLog(@"run once, and only once!");

                [[NSNotificationCenter defaultCenter] removeObserver:gpsObserver];

        }];

我添加了一個__weak來確保沒有內存泄漏(根據Matt的回答)。 代碼未經測試。

我發現實際上存在內存泄漏,除非觀察者同時被標記為__block__weak 使用樂器確保self不會被過度保留; 我敢打賭。 但是,這可以正常工作(根據我的實際代碼):

__block __weak id observer = [[NSNotificationCenter defaultCenter] 
    addObserverForName:@"MyMandelbrotOperationFinished" 
    object:op queue:[NSOperationQueue mainQueue] 
    usingBlock:^(NSNotification *note) {
        // ... do stuff ...
        [[NSNotificationCenter defaultCenter] 
            removeObserver:observer 
            name:@"MyMandelbrotOperationFinished" 
            object:op];
}];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM