1

我在别人的 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. 谁拥有每个这样的实例?[什么时候]它会被摧毁?由于它拥有对其委托的强引用,当前的实现是否创建了一个强引用循环[每次按下按钮]

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

任何帮助表示赞赏。

4

2 回答 2

2

按照惯例,委托引用很弱。

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

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

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

于 2015-11-25T01:02:03.810 回答
2

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

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

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


我的建议:小心。如果可能的话,把强委托变成弱委托。即使现在没有保留周期,您也可以轻松地创建一个,而不会意识到这一点。

于 2015-11-25T00:30:05.880 回答