0

根据过渡到 ARC 发行说明,当在块中引用 self 时,应使用弱引用以避免强引用/保留循环:

MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler =  ^(NSInteger result) {
MyViewController *strongMyController = weakMyController;
if (strongMyController) {
    // ...
    [strongMyController dismissViewControllerAnimated:YES completion:nil];
    // ...
}
else {
    // Probably nothing...
}
};

有时,我会收到一个编译器警告,指出在块中引用 self 可能会导致保留循环。没有警告是否意味着不会创建保留周期?为什么警告被限定为“可能”导致保留周期?

4

1 回答 1

3

没有警告是否意味着不会创建保留周期?

不会。编译器能够确定您可以创建保留循环的某些条件,但它不可能排除您创建保留循环的可能性。例如,考虑以下类:

@interface MyClass : NSObject

@property (readwrite, strong) id myObject;

@end

以及不同类中的代码片段:

MyClass *one = [MyClass new];
MyClass *two = [MyClass new];

one.myObject = two;
two.myObject = one; // created a strong cycle...

对于一个编译器来说甚至发现这个简单的循环需要跨多个类的流分析,一般来说这个问题是编译器无法解决的(你可以在运行时扫描/发现循环的创建,ARC 不这样做)。

为什么警告被限定为“可能”导致保留周期?

创建一个循环本身并没有错或坏。只有成为孤立的循环才是问题。即没有活动引用引用它,只有循环引用导致循环中的对象保持活动状态。

当编译器在正在创建的块中看到对 self 的强引用时,它知道将创建一个实时强循环,但它无法确定(即如上所述一般无法解决)该循环是否会在不再需要块之前被打破或者创建对象和块是否会形成孤立循环。因此使用了非确定性的“可能”。

于 2012-11-12T09:15:15.307 回答