使用块保留“self"的循环 [英] Retain cycle on `self` with blocks

查看:23
本文介绍了使用块保留“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-copy 问题的解决方法与保留问题的解决方法相同;即,为变量使用 __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天全站免登陆