block循环引用和释放问题

循环引用

在平时开发过程中,block是我们经常使用的功能,如果不多加注意就会造成一些问题,首先一个小案例看一下循环引用出现情况

self.myBlock = ^(){
   [self foo];
};

以上造成循环引用的原因是self持有了block,而block内部也持有了self,导致循环引用
self -> block -> self

用图来解释的话

self和block相互持有
当作用域结束后,block依然持有self

解决方案如下

__weak typeof(self) weakSelf = self;
self.myBlock = ^(){
    [weakSelf foo];
};
block持有weak属性的self
作用域结束后,一同释放

保证了当self对block的持有结束之后,block可以释放掉self

__strong

__weak typeof(self) weakSelf = self;
self.myBlock = ^(){
    __strong typeof(weakSelf) = strongSelf;
    [strongSelf doSomething];
};

防止内部weakself在某些情况下被释放掉,使用__strong修饰一次可解决这个问题。

不会造成循环引用的情况
并不是所有的block都会造成循环引用,只有被self所持有的block才会造成这种问题,下面例举两个例子

dispatch_async(dispatch_get_main_queue, ^{
    [self doSomething];
});

这里的gcd并没有被self所持有,所以不会造成循环引用

- (void)testWithBlock:(void(^)())block {
    block();
}
[self testWithBlock:^{
    [self test];
}];

同理,局部变量block也没有被self所持有,所以不会造成问题

你可能感兴趣的:(block循环引用和释放问题)