关于 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 是多余的,而且当人们假设它总是被调用时会引起很多混乱。你应该把你的清理工作放在viewDidDisappear
或dealloc
,这取决于你希望多早完成。
viewDidUnload 在内存不足的情况下被调用并且你的视图被赋予了沉重的负担。这是一种不太可能发生的特殊情况。以上是关于关于 ARC for iOS 的几个问题?的主要内容,如果未能解决你的问题,请参考以下文章
iOS SDK:ARC removeFromSuperview
IOS,ARC,属性:(readwrite,nonatomic)vs(radwrite,retain,nonatomic)