简体   繁体   English

在嵌套在另一个块中的块中中断保留循环

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

Sometimes I use a block nested in another block, here is my code有时我使用嵌套在另一个块中的块,这是我的代码

- (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 {
    
}

I doubt the inner block still has a retain cycle?我怀疑内部块还有保留周期吗?

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

my question is what is the correct way to break the retain cycle in such situation?我的问题是在这种情况下打破保留周期的正确方法是什么?


here is the additional discussion, as many friend mentioned about this, if I remove __strong typeof(weakSelf) strongSelf = weakSelf;这是额外的讨论,正如许多朋友提到的那样,如果我删除__strong typeof(weakSelf) strongSelf = weakSelf; , the inner block has no retain cycle? ,内部块没有保留循环? Is it perfectly correct?它是完全正确的吗?

- (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 {
    
} 

I think you can just create new strong reference inside nested block, like this:我认为您可以在嵌套块中创建新的强引用,如下所示:

- (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];
        }];
    }];
}

It will override the first strongSelf in the nested block scope.它将覆盖嵌套块作用域中的第一个strongSelf And it will be only alive during the execution of the nested block without strong reference cycle created.并且它只会在没有创建强引用循环的嵌套块执行期间存活。 I think so =)我也这么认为 =)

You don't create a strong reference to a weakSelf.您不会创建对weakSelf 的强引用。 All variables copied in blocks are owned as a strong reference.在块中复制的所有变量都作为强引用拥有。 __weak can be released by self, but it is retained by block. __weak 可以被self释放,但是被block保留。 A retain cycle is produced when self which has a strong reference to a block cannot go out of scope because the block holds a strong reference to self.当具有对块的强引用的 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.
    });
});

Here self can be deallocated and the block will also be deallocated.这里 self 可以被释放,块也将被释放。 This is because the block has a strong pointer to weakSelf, but not a strong pointer to self.这是因为块有一个指向weakSelf 的强指针,但没有指向self 的强指针。

Maybe I should clarify a bit.也许我应该澄清一下。 This block is called in a method.这个块在一个方法中被调用。 If self is deallocated the method does not exist.如果 self 被释放,则该方法不存在。 There is no need to reference strong self.没有必要引用强自我。 Even if deallocated after the first block executes, self does not need to call its method updateUI.即使在第一个块执行后释放,self 也不需要调用它的 updateUI 方法。 You would only use strong if another object took ownership of the block and wanted to retain self by the block, which would be owned by the object that has it(thus preventing a memory leak).如果另一个对象获得块的所有权并希望由块保留 self ,则您只会使用 strong ,该块将由拥有它的对象拥有(从而防止内存泄漏)。 That would keep self during execution, provided the first allocation was done with the object in scope.这将在执行期间保持 self ,前提是第一次分配是在范围内的对象上完成的。 ie: Deallocation did not occur before assigning __strong self Additionally, there is no reason to keep an object in memory just to perform UI work.即:在分配 __strong self 之前没有发生释放此外,没有理由为了执行 UI 工作而将对象保留在内存中。 The weak reference should be nilled out as soon as the UI wants to be deallocated.一旦 UI 想要被释放,弱引用就应该被清除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM