簡體   English   中英

在ARC中使用NSNotificationCenter代碼塊方法時,不會調用控制器dealloc

[英]View controller dealloc not called when using NSNotificationCenter code block method with ARC

當我在視圖控制器的-viewDidLoad:方法中使用-addObserverForName: object: queue: usingBlock: for NSNotificationCenter時, -dealloc方法最終沒有被調用。

(當我刪除-addObserverForName: object: queue: usingBlock: ,再次調用-dealloc 。)

使用-addObserver: selector: name: object:似乎沒有這個問題。 我究竟做錯了什么? (我的項目是使用ARC。)

下面是我的實現示例,以防我在這里做錯了:

[[NSNotificationCenter defaultCenter] addObserverForName:@"Update result"
                                                  object:nil
                                                   queue:nil
                                              usingBlock:^(NSNotification *note) {
                                                  updateResult = YES;
                                              }];

在此先感謝您的幫助。

我嘗試添加以下內容(無濟於事):

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    if ([self isMovingFromParentViewController]) {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
}

updateResult是一個實例變量,它可以防止對象被該塊保留而取消分配。

換句話說,你有一個保留周期。 對象保留塊,塊保留對象。

您將需要創建一個弱或不安全的對該實例的引用及其變量以釋放該關系。

在通知塊之前添加以下內容:

__unsafe_unretained YouObjectClass *weakSelf = self;

或者(如果您使用的是iOS5及以上版本)

__weak YouObjectClass *weakSelf = self;

然后,在該塊中,通過新的弱引用引用該對象:

[[NSNotificationCenter defaultCenter] addObserverForName:@"Update result"
                                                  object:nil
                                                   queue:nil
                                              usingBlock:^(NSNotification *note) {
                                                  weakSelf.updateResult = YES;
                                              }];

請注意,保留周期本身並不是一件壞事。 有時你真的希望它們發生。 但是那些是你確定循環將在特定時間后被破壞的情況(例如動畫塊)。 一旦塊執行並且從堆棧中移除,循環就會中斷。

這很可能是因為您有一個保留周期。

當您的塊隱式保留self時,通常就是這種情況,並且self會以某種方式保留塊。 你將有一個保留周期,因為每個保留周期,因此他們的retainCount永遠不會達到零。

您應該激活警告-Warc-retain-cycles ,它會警告您這些問題。

所以在你的情況下,你使用變量updateResult ,我假設它是一個實例變量,這隱式保留self 您應該使用臨時弱變量來表示self,並在塊中使用它,這樣它就不會被保留並且您會中斷保留周期。

__block __weak typeof(self) weakSelf = self; // weak reference to self, unretained by the block
[[NSNotificationCenter defaultCenter] addObserverForName:@"Update result"
                                              object:nil
                                               queue:nil
                                          usingBlock:^(NSNotification *note) {
                                              // Use weakSelf explicitly to avoid the implicit usage of self and thus the retain cycle
                                              weakSelf->updateResult = YES;
                                          }];

這不是保留周期。

NSNotificationCenter持有塊,塊self 因為[NSNotificationCenter defaultCenter]是一個生活在所有應用程序生命周期中的單例,所以它保持self間接。

暫無
暫無

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

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