此 objective-c 代码是否会产生强引用循环?

Does this objective-c code create a strong reference cycle?

我在别人的 iOS 项目中工作。 ARC 是(并且据我所知一直是)启用的。代码中充斥着按钮按下处理程序,这些处理程序创建某个视图控制器的实例,将其委托设置为自身,然后显示它,例如,

- (IBAction)keyButton:(id)sender {
    MyViewController *controller = [[MyViewController alloc] init];
    controller.delegate = self;
    [self.navigationController pushViewController:controller animated:YES];
}

MyViewController 显示了一个用于选择音乐键的旋转小部件。选择后,用户按回键以使用所选键制作音乐。这些是唯一的用户交互,没有后台进程等。

在MyViewController.h文件中,委托声明如下:

@interface MyViewController : UIViewController {
    id <ModuleUpdateDelegate> _delegate;
}

@property (nonatomic,strong) id delegate;

我有两个问题:

  1. 为什么原作者可能会选择创建一个新实例 每次按下按钮时 MyViewController 的数量?
  2. 谁拥有每个这样的实例? [什么时候]它会被摧毁?自从它 拥有对其委托的强引用,是当前的 实现创建一个强大的参考循环[每个按钮 按]?

我自己的直觉是在委托中创建一个私有的 MyViewController * 属性,它仅在第一次按下按钮时加载。然后,根据一般建议,我将使 MyViewController 中的委托 属性 变弱而不是变强。但就像我说的,当前的实现非常普遍,所以我对在没有先了解它是如何工作的情况下改变任何东西持怀疑态度。

感谢任何帮助。

在这种情况下,MyViewController 保留谁并不重要,重要的是谁保留 MyViewController.

的实例

在您发布的代码中,对 MyViewController 的强引用由 self.navigationController 持有。一旦 MyViewController 被弹出,它的保留计数就会达到 0,然后它就会被释放。只要controller.delegate不保留controller,就没有循环

就是说,您必须非常小心强反向引用(例如委托之类的东西)。如有疑问,请使用 Instruments 检查保留周期或内存泄漏。


我的建议:谨慎行事。如果可能,将强委托变成弱委托。即使现在没有保留周期,您也可以在不知不觉中轻松创建一个。

按照约定,委托引用是弱的。

通常,您创建一个对象,持有对它的强引用,并将您自己设置为它的委托。 (并且指向委托的指针很弱。)这样只有一个强引用方式。

在您的情况下,您的代码执行相反的操作。对象(MyViewController)在局部变量中创建,然后被遗忘。 MyViewController class' 委托 属性 很强大。所以没有对 MyViewController 对象的强引用,但是有对委托的强引用。

正如 Jeffery 所说,您现在似乎没有保留周期,但如果稍后您决定需要保留指向 MyViewController 对象的指针,那么您可能会创建一个保留周期。