我是一名出生的Obj-C程序员,并且只生活在ARC后世界。不过,就我自己的功效而言,我最近决定通过Apple的 Transitioning to ARC Release Notes 。在 ARC Introduces New Lifetime Qualifiers 部分中,有一个标题为使用终身限定符以避免强引用周期的小节,其中描述了使用潜在限定符的各种方法,以避免潜在的保留周期。
我的问题与最后两个例子有关。最后两个示例中的第一个使用了我经常使用的模式,以避免过早地从非主线程中释放UIKit对象:
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyViewController = myController;
myController.completionHandler = ^(NSInteger result) {
[weakMyViewController dismissViewControllerAnimated:YES completion:nil];
};
在上面的示例中,使用对weakMyViewController
的弱引用创建myController
对象,以便引用weakMyViewController
的块可以使用它,并在返回块时weakMyViewController
1}}可以安全地超出范围而不减少被引用的底层UIKit对象的引用计数。
在下一个例子中,Apple显示以下“非平凡周期”代码:
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...
}
};
在上面提供的“非平凡”示例中,相同的__weak
限定符用于从块中引用UIKit对象,但代码会创建一个本地隐式__strong
引用。同一个对象。然后测试本地__strong
引用的非零条件,然后对其进行操作。
我的两个问题是:
Obj-C程序员应该在什么时候考虑实现第二种设计模式(与前者相反)?我不理解Apple关于“非平凡周期”的评论
__strong
对weakMyController
的引用如何不增加原始myController
对象的保留计数?如果weakMyController
只是指向myController
指向的基础对象的指针,则强指针(即stringMyController
)不会增加底层对象({myController
的保留计数{1}}指向)?
答案 0 :(得分:3)
关于你的第一个例子,你认为拥有块文字的动机只保留对weak
指向的实例的myController
引用并不完全正确。 weak
引用不会阻止对象解除分配,弱引用的目的是阻止强引用循环(也称为保留循环)。在这种情况下,强引用周期将表现为myController
保持对completionHandler
中存储的块的强引用,而块保持强引用回myController
- 两者都不会被取消分配(未来某个时候不取消设置completionHandler
属性)。因此,这里的动机与保持对象存活完全相反 - 允许myController
在其所有其他引用都不存在时正常解除分配。
第二个例子是第一个例子的扩展,但是通过将捕获的弱引用分配给块的本地强引用,我们可以确保只要控制器在块执行开始时仍处于活动状态,它将保持活动状态直到块执行结束。由于强引用仅限于块,因此不会创建强引用循环。换句话说,strongMyController
仅在块代码范围内是本地的,并且不会被块对象本身保留。
现在,要解决您的具体问题: