clang是否使用__typeof捕获ARC修饰符?

时间:2013-04-29 20:59:36

标签: objective-c automatic-ref-counting objective-c-blocks

众所周知,如果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]

1 个答案:

答案 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}}运行时函数(当前)正在执行其当前加载的值的保留+自动释放。所以在实践中,每个例子都是同样安全的。但是,不能保证将来总是如此。