这个objective-c代码是否会创建一个强大的参考周期?

时间:2015-11-25 00:10:49

标签: ios objective-c delegates automatic-ref-counting strong-references

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

- (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. 谁拥有每个这样的实例? [何时]被摧毁?既然如此 对其代表有强烈的引用,是当前的 实现创建一个强大的参考周期[与每个按钮 按]
  3. 我自己的直觉是在委托中创建一个私有的MyViewController *属性,该属性仅在第一个按钮上加载。然后我会根据一般建议使MyViewController中的委托属性变弱而不是强。但就像我说的那样,当前的实现是无处不在的,所以在没有先了解其工作原理的情况下,我对改变任何事情都很谨慎。

    感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

在这种情况下,MyViewController保留谁并不重要,保留MyViewController实例的人很重要。

在您发布的代码中,MyViewController的强引用由self.navigationController保留。弹出MyViewController后,其保留计数将达到0并将被释放。只要controller.delegate不保留controller,就没有周期。

那就是说,你必须非常小心强大的反向引用(例如代表之类的东西)。如有疑问,请使用仪器检查保留周期或内存泄漏。

我的建议:小心。如果可能的话,将强委托变成弱委托。即使现在没有保留周期,您也可以轻松创建一个保留周期。

答案 1 :(得分:1)

按惯例,委托引用很弱。

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

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

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