保留带有块的`self`上的循环 [英] Retain cycle on `self` with blocks

查看:68
本文介绍了保留带有块的`self`上的循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

恐怕这个问题是很基本的,但是我认为这与许多进入程序段的Objective-C程序员有关.

I'm afraid this question is pretty basic, but I think it's relevant to a lot of Objective-C programmers who are getting into blocks.

我所听到的是,由于块将在其中引用的局部变量捕获为const副本,因此,如果要复制该块,则在块中使用self会导致保留周期.因此,我们应该使用__block强制该块直接处理self而不是复制它.

What I've heard is that since blocks capture local variables referenced within them as const copies, using self within a block can result in a retain cycle, should that block be copied. So, we are supposed to use __block to force the block to deal directly with self instead of having it copied.

__block typeof(self) bself = self;
[someObject messageWithBlock:^{ [bself doSomething]; }];

而不是仅仅

[someObject messageWithBlock:^{ [self doSomething]; }];

我想知道的是以下内容:如果是这样,是否有办法避免丑陋(除了使用GC外)?

What I'd like to know is the following: if this is true, is there a way that I can avoid the ugliness (aside from using GC)?

推荐答案

严格来说,它是const副本这一事实与此问题无关.块将保留创建时捕获的所有obj-c值.碰巧,const复制问题的解决方法与保留问题的解决方法相同;即使用__block存储类作为变量.

Strictly speaking, the fact that it's a const copy has nothing to do with this problem. Blocks will retain any obj-c values that are captured when they are created. It just so happens that the workaround for the const-copy issue is identical to the workaround for the retain issue; namely, using the __block storage class for the variable.

无论如何,要回答您的问题,这里没有真正的选择.如果您正在设计自己的基于块的API,并且这样做很有意义,则可以让该块作为参数传递self的值.不幸的是,这对于大多数API来说都没有意义.

In any case, to answer your question, there's no real alternative here. If you're designing your own block-based API, and it makes sense to do so, you could have the block get passed the value of self in as an argument. Unfortunately, this doesn't make sense for most APIs.

请注意,引用ivar具有完全相同的问题.如果需要在块中引用ivar,请改用属性或使用bself->ivar.

Please note that referencing an ivar has the exact same issue. If you need to reference an ivar in your block, either use a property instead or use bself->ivar.

附录:作为ARC编译时,__block不再中断保留周期.如果要为ARC进行编译,则需要改用__weak__unsafe_unretained.

Addendum: When compiling as ARC, __block no longer breaks retain cycles. If you're compiling for ARC, you need to use __weak or __unsafe_unretained instead.

这篇关于保留带有块的`self`上的循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆