众所周知,如果 block
隐式保留了一个对象,而该对象也保留了 block
,则 block
可能会引发一个保留周期。示例:
self.block = ^{
[self foo];
};
通常规定的解决方法是简单地使用 __weak
self
来避免保留周期:
__typeof(self) __weak weakSelf = self;
self.block = ^{
[weakSelf foo];
};
但是,如果 self
在执行 foo
的过程中被释放,这可能会导致问题。更好的策略是在 block 中本地捕获对 __weak
self
的 __strong
引用。但是,我不知道 __weak
修饰符是否被 __typeof
捕获,如果是,我可以用另一个 __strong
覆盖它吗?
那么,其中一个是正确的,但是哪个呢?
一个
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(self) strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
B
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(self) __strong strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
C
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(weakSelf) strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
D
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(weakSelf) __strong strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
我希望 C 是正确的,因为它根本没有将 self
放在 block
中,也不需要额外的__strong
。
编辑
我完全搞砸了我最初的问题,而且我的例子也错了。在我的 block 中,我所有的答案过去都是 [weakSelf foo]
而不是 [strongWeakSelf foo]
。
最佳答案
C(几乎)是您想要的:
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(weakSelf) strongWeakSelf = weakSelf;
[strongWeakSelf foo]; //use strongWeakSelf, not weakSelf.
};
__strong
或 __weak
ownership qualifier 不同于您从 __typeof__ 获得的 type ()
。
B 与A 相同,C 与D 相同,因为local variables are implicitly __strong
.
但迂腐地讲,所有这些示例可能都无法满足您的要求!由于 strongWeakSelf
实际上并未使用,因此优化器可能会删除它。
此外,如果您正在测试其中任何一个,请注意当前用于读取 weakSelf
的 objc_loadWeak
运行时函数(当前)正在执行 retain+autorelease它今天加载的值(value)。所以在实践中,这些例子中的每一个都同样是广告安全的。但是,不能保证将来总是如此。
关于objective-c - clang 是否使用 __typeof 捕获 ARC 修饰符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16288137/