簡體   English   中英

在嵌套在另一個塊中的塊中中斷保留循環

[英]break retain cycle in a block nested in another block

有時我使用嵌套在另一個塊中的塊,這是我的代碼

- (void)test {
    __weak typeof(self) weakSelf = self;
    [self.viewSource fetchData:^(BOOL succeed, NSError * _Nonnull error, id  _Nonnull data) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf.dataSource disposalData:^{
        // here is the strongSelf ok? do I have to do something to avoid retain cycle?
            [strongSelf updateUI];
        }];
    }];
}
- (void)updateUI {
    
}

我懷疑內部塊還有保留周期嗎?

    [strongSelf.dataSource disposalData:^{
        [strongSelf updateUI];
    }];

我的問題是在這種情況下打破保留周期的正確方法是什么?


這是額外的討論,正如許多朋友提到的那樣,如果我刪除__strong typeof(weakSelf) strongSelf = weakSelf; ,內部塊沒有保留循環? 它是完全正確的嗎?

- (void)test {
    __weak typeof(self) weakSelf = self;
    [self.viewSource fetchData:^(BOOL succeed, NSError * _Nonnull error, id  _Nonnull data) {
        [weakSelf.dataSource disposalData:^{
            [weakSelf updateUI];
        }];
    }];
}
- (void)updateUI {
    
} 

我認為您可以在嵌套塊中創建新的強引用,如下所示:

- (void)test {
    __weak typeof(self) weakSelf = self;
    [self.viewSource fetchData:^(BOOL succeed, NSError * _Nonnull error, id  _Nonnull data) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf.dataSource disposalData:^{
            __strong typeof(weakSelf) strongSelf = weakSelf; // <- new strong ref
            [strongSelf updateUI];
        }];
    }];
}

它將覆蓋嵌套塊作用域中的第一個strongSelf 並且它只會在沒有創建強引用循環的嵌套塊執行期間存活。 我也這么認為 =)

您不會創建對weakSelf 的強引用。 在塊中復制的所有變量都作為強引用擁有。 __weak 可以被self釋放,但是被block保留。 當具有對塊的強引用的 self 不能超出范圍時,就會產生一個保留循環,因為該塊持有對 self 的強引用。

 __weak typeof(self) weakSelf = self; //This is defined as weak to the instance that creates it.

dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
    NSLog(@"%@", weakSelf.description);// Here weak self is strongly referenced by block copy.
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"%@ second dispatch", weakSelf.description);// Here weak self is also strongly referenced by block.
    });
});

這里 self 可以被釋放,塊也將被釋放。 這是因為塊有一個指向weakSelf 的強指針,但沒有指向self 的強指針。

也許我應該澄清一下。 這個塊在一個方法中被調用。 如果 self 被釋放,則該方法不存在。 沒有必要引用強自我。 即使在第一個塊執行后釋放,self 也不需要調用它的 updateUI 方法。 如果另一個對象獲得塊的所有權並希望由塊保留 self ,則您只會使用 strong ,該塊將由擁有它的對象擁有(從而防止內存泄漏)。 這將在執行期間保持 self ,前提是第一次分配是在范圍內的對象上完成的。 即:在分配 __strong self 之前沒有發生釋放此外,沒有理由為了執行 UI 工作而將對象保留在內存中。 一旦 UI 想要被釋放,弱引用就應該被清除。

暫無
暫無

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

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