众所周知,如果block
隐式保留同时保留block
的对象,block
可能会导致保留周期。例如:
self.block = ^{
[self foo];
};
常用的解决方法是简单地使用__weak
self
来避免保留周期:
__typeof(self) __weak weakSelf = self;
self.block = ^{
[weakSelf foo];
};
但是,如果在执行self
的过程中释放foo
,则会导致问题。更好的策略是在块内本地捕获__strong
__weak
的{{1}}引用。但是,我不知道是否已捕获self
修饰符__weak
,如果是,我可以使用其他__typeof
覆盖它吗?
所以,其中一个是正确的,但是哪个?
A
__strong
乙
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(self) strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
C
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(self) __strong strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
d
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(weakSelf) strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
我希望 C 是正确的,因为它根本不会将__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(weakSelf) __strong strongWeakSelf = weakSelf;
[strongWeakSelf foo];
};
置于self
内,并且不需要额外的block
。
修改
我完全搞砸了我最初的问题并且我的例子错了。在我的版块中,我的所有答案都是__strong
而不是[weakSelf foo]
。
答案 0 :(得分:5)
C (几乎)是你想要的:
__typeof(self) __weak weakSelf = self;
self.block = ^{
__typeof(weakSelf) strongWeakSelf = weakSelf;
[strongWeakSelf foo]; //use strongWeakSelf, not weakSelf.
};
__strong
或__weak
所有权限定符与您从__typeof__()
获得的类型不同。
B 与 A 相同,而 C 与 D 相同,因为{{3} }。
但是,所有这些例子可能不会做你想要的!由于实际上并未使用strongWeakSelf
,因此优化程序可能会将其删除。
另外,如果您正在测试其中任何一个,请注意当前用于读取objc_loadWeak
的{{1}}运行时函数(当前)正在执行其当前加载的值的保留+自动释放。所以在实践中,每个例子都是同样安全的。但是,不能保证将来总是如此。