让成员变量保留而不是分配是更好的做法吗

Posted

技术标签:

【中文标题】让成员变量保留而不是分配是更好的做法吗【英文标题】:Is it better practice to make member vars retained versus assign 【发布时间】:2012-01-05 21:26:54 【问题描述】:

我的自定义 UIViewController 中有成员变量,它们被定义为“分配”(而不是“保留”),如下所示:

@property (nonatomic, assign) UIButton* mSkipButton;

在我的 loadView 方法中,我将 var(例如 self.mSkipButton)设置为变量类型的自动释放分配。然后我将它附加到我的控制器的视图中,基本上具有视图引用计数并根据需要释放它。

然而,这让我担心,我将指针存储在我的成员 var 中,并且如果计数在某个时候减少,它可能会引用已释放的内存。将变量声明为“retain”然后在 viewDidUnload 方法中释放成员 var(或者将其设置为 nil 以释放并确保其中没有地址)是更好的做法吗?

或者,我可以简单地在 viewDidUnload 中将成员 var 设置为 nil 而不使其成为保留变量吗?

【问题讨论】:

该对象是否被另一个比您的视图控制器寿命更长的对象保留?如果您可以证明它确实被另一个项目(可能是应用程序委托)保留,那么您可能会侥幸不保留它。但最佳实践表明您应该始终保留和释放。 【参考方案1】:

将变量声明为 'retain' 然后在 viewDidUnload... 中是否更好?

是的,使用retain——很好的直觉。在 viewDidUnload 中,您通常只需通过 ivar 的设置器将其设置为 nilself.ivar = nil;

我发现明确地了解和管理对象依赖关系比处理与使用assign 相关的问题更容易。您可以完全避免持有非托管引用的问题。

可以说assign 通常在这里会很好(在某些情况下是这样),但是使用assign 会使使用该类的任何人的对象图和所有权变得复杂。随着程序复杂性的增加(以及您所依赖的库的变化),跟踪非托管引用的生命周期变得越来越困难。在不同的硬件和软件组合上,事情往往会发生故障或以不同的方式运行。试图在复杂程序或并发上下文中管理非托管对象的生命周期是自滥用。保证已定义且可预测的行为/操作可减少错误数量。

【讨论】:

【参考方案2】:

这是一个属性,而不是“成员变量”(在 Objective-C 中称为实例变量或 ivar。)

属性的语义取决于该属性的使用方式。一般来说,您会希望在对象的整个生命周期内保留您的属性。如果该属性是一个已连接的IBOutlet,这将由 NIB 加载器为您完成;否则,您必须明确并在属性上使用retaincopy 属性。

对于预期拥有您的对象的对象,应始终将属性标记为assign 以避免保留循环。例如,一个对象通常拥有它作为委托的任何对象(通常,但并非总是——每个 CS 规则都有一个例外。)

【讨论】:

以上是关于让成员变量保留而不是分配是更好的做法吗的主要内容,如果未能解决你的问题,请参考以下文章

类成员函数中定义的的static变量的内存是怎么分配的?

在C中参考命名的结构成员直接初始化或分配变量数组的结构成员?

JAVA中的成员变量不赋值默认是0吗?

java语言中,类的成员变量分配在哪个内存区?

静态成员变量初始化 C++

让我的垃圾收集保留对子小部件的 pyside/Qt 引用作为成员变量会妨碍正确清理吗?