关于 ARC for iOS 的几个问题?

Posted

技术标签:

【中文标题】关于 ARC for iOS 的几个问题?【英文标题】:A few questions about ARC for iOS? 【发布时间】:2012-06-19 17:15:03 【问题描述】:

我对适用于 ios 的 ARC 还很陌生(对 iOS 也很陌生),我有几个关于 ARC 的简单问题。

~ 在视图控制器中,如果我的 viewDidUnload() 方法中没有语句将我的属性设置为 nil,当我的视图控制器被释放时,属性的内存是否仍会被释放?如果是这样,为什么我需要显式地拥有这个 viewDidUnload 方法?

~ 在不是视图控制器的对象中,我应该在哪里将属性设置为 nil?在dealloc中?像@property BOOL isActive;这样的原始属性呢?我需要将它们设置为零/零吗?

谢谢。

【问题讨论】:

【参考方案1】:
    您不需要将属性设置为 nil,只要它们是弱引用。 IBOutlets 通常应该是弱引用,因为它们视图控制器包含对视图的强引用,而视图又包含对其所有子视图的强引用。 (如果您有不属于该视图层次结构的 IBOutlets,它们应该很强大。) 你不应该需要零或零任何东西,对象或标量。 Xcode 在使用 Interface Builder 时会插入 nilling 语句,但这仍然是为 pre-ARC Objective-C 生成代码。

您可能甚至不需要viewDidUnload;它只在特殊情况下调用,当内存压力较低时。因此,您不能依赖它进行清理。您的 IBOutlets 应该很弱,因此当视图从视图控制器中清除时它们会被自动清理(并且如果重新加载视图,它们将被恢复)。

我在这里假设您正在编写一个新产品,这意味着您只针对 iOS 5 或更高版本。如果您在新产品中以 iOS 4 为目标,那么您真的shouldn't 是。世界已经在发展,iOS 5 或更高版本占据了 80% 的市场份额。这就是今天。展望未来,为更小比例的人避免使用 iOS 5 功能将变得更加困难。

【讨论】:

请注意,弱引用只能在 iOS5 之前使用,许多人可能仍然针对 iOS 4.x 更长时间。 我会注意到,尽管现在对于新开发,我强烈认为只支持 iOS5,部分原因是能够使用弱引用... 是的,当然!弱引用是将 ARC 从“一种更快的产品生产方式”转变为“一种更快的生产更好产品的方式”的神奇之处。【参考方案2】:

@properties 的内存管理在 ARC 下自动处理。当您将自己设置为委托时,通常在离开之前将委托设置为 nil(例如在 viewWillDisapear 中),以便将来对委托的调用不会引用垃圾。请继续关注即将发布的 WWDC 视频以获取最新指导。

【讨论】:

难道我们不只是让委托属性变弱,这样我们就不必担心这个了吗?【参考方案3】:

在 viewDidUnload 中,您需要将 outlet 引用设置为 nil,因为 ARC 会释放它们,并且您不想在此之后意外使用它们。

您不必对属性做任何事情,它们会被自动处理。事实上,你通常甚至没有使用 ARC 的 dealloc 方法。

【讨论】:

还有一个我忘了问的问题,假设我在执行视图控制器代码的中途完成使用我的一个属性(意思是在调用 viewDidUnload 之前),我应该立即将指针设置为 nil,还是我应该等待它最终在 viewDidUnload 中发布吗? 如果您确定不需要它,我会立即取消它。请注意,尽管有名称,viewDidUnload不是viewDidLoad 的对应物;有时(通常,实际上)你会得到 viewDidLoad 调用而没有得到 viewDidUnload 以后。 好吧,最后一句话让我很困惑。你是什​​么意思 viewDidUnload 不是 viewDidLoad 的对应物?我一直认为它是在使用完 ViewController 之后调用的。 没有。 viewDidUnload 仅在存在内存压力时调用。它在正常路径中被跳过。 viewDidUnload 现在不仅对于弱引用 ARC 是多余的,而且当人们假设它总是被调用时会引起很多混乱。你应该把你的清理工作放在viewDidDisappeardealloc,这取决于你希望多早完成。 viewDidUnload 在内存不足的情况下被调用并且你的视图被赋予了沉重的负担。这是一种不太可能发生的特殊情况。

以上是关于关于 ARC for iOS 的几个问题?的主要内容,如果未能解决你的问题,请参考以下文章

iOS SDK:ARC removeFromSuperview

iOS5需要ARC的可达性版本

iOS开发ARC内存管理技术要点

iOS开发ARC内存管理技术要点

IOS,ARC,属性:(readwrite,nonatomic)vs(radwrite,retain,nonatomic)

iOS关于CAShapeLayer与UIBezierPath的知识内容