1

我仍在学习 iOS 开发,并且一直在使用各种教程和书籍。有些是 ARC 之前的,有些是 ARC 的。

在某些情况下,我们被教导在 viewDidUnload 上释放 ViewController 的所有属性和子视图,但在某些情况下,我被告知不再需要这样做。

有人能给出肯定的答案吗?在 iOS 5+ 中,是否必须完成整个操作:

-(void)viewDidUnload
{
  [super viewDidUnload];
  self.photoViewCell = nil;
  self.photoImageView = nil;
  self.firstNameTextField = nil;
  self.lastNameTextField = nil;
}

... 或不?如果是这样,这仅适用于 UIView 的后代属性还是适用于 ViewController 的所有属性?

谢谢

4

3 回答 3

8

所以每个视图都有多个所有者。当“所有者计数”(通常称为 retainCount)达到 0 时,该对象将被销毁。

在 iOS 5 中,我们现在有弱引用,这本质上意味着“不拥有这个对象”。

在 iOS 5 之前,在我们的头文件中,你会看到

IBOutlet UILabel *myLabel;

这个标签被添加到 XIB 文件的视图中。在这种情况下,myLabel 有 2 个所有者:它是超级视图(XIB 文件中的视图)和视图控制器(通过拥有 IBOutlet)。当 viewDidUnload get 被调用时,视图控制器的视图已经被释放,因此它对 myLabel 的所有权消失了。所以此时 myLabel 只有 1 个所有者,即视图控制器。所以我们需要在 viewDidLoad 中释放它以确保它没有任何所有者并因此被销毁。

在 iOS 5 中,您会经常看到这种情况

__weak IBOutlet UILabel *myLabel

这就是说我们不希望视图控制器成为 myLabel 的所有者。所以唯一的所有者是视图控制器的视图。所以当 viewDidUnload get 被调用时,视图控制器的视图已经被释放,因此它对 myLabel 的所有权也被释放了。在这种情况下,myLabel 现在没有所有者并且它的内存被释放。不需要 self.myLabel = nil; 那里。

因此,对于 iOS 5,建议将所有 IBOutlets 设为弱引用。有了这个,你甚至不需要实现 viewDidUnload,因为所有的内存都已经为你处理好了。

但即使您使用的是 iOS 5,如果您的 IBOutlets 不是弱引用,您将需要 viewDidUnload 中的代码。

于 2012-06-01T15:58:37.847 回答
0

viewDidUnload 与自动或其他保留计数无关。当由于内存压力而卸载视图时将调用此方法,这意味着您还应该 nil(并释放,非 ARC)您持有强引用的视图元素。不这样做可能意味着您的应用程序在内存压力下没有释放足够的内存,这可能导致它被操作系统关闭。

于 2012-06-01T16:00:44.403 回答
0

如果您的应用程序值得,您可以使用 viewDidUnload 来管理内存。

但不要做

myInstanceVariable = nil;

您失去了对变量值所在的内存位置的引用。

= nil 不会释放内存。不过,您的对象必须被释放。因此使用了retainCount 和retain/release。

如果您在 viewDidUnload 中将对象归零,则无法在 dealloc 中释放!注意力!!!

如果你知道你做了什么,你可以在 viewDidUnload 中释放和归零你的对象。

弧:

使用ARC,你不能手动释放,即使我认为你不能这样做。ARC 负责这一点。只需尽可能多地使用 @properties 和 (weak/strong) 属性,让 getter 和 setter 为您完成工作。您也可以在 .m 文件中声明 @properties(如在类扩展中)。

简单的规则:对你想要拥有的对象强,对对象弱,你不想在保留周期中迷失并持有所有权。ARC 在几乎所有情况下都会完成其余的工作。例如,对代表使用弱。

nil 对象,在你确定的地方,你不会向他们发送消息,否则不要。

于 2012-06-01T16:18:38.453 回答