2

我有个问题。这个问题可能有一个非常简单的解决方案,但我还无法弄清楚。如果我使用属性说@property(nonatomic, retain)UIView *mainView.

现在我在 .m 文件中合成它并在 dealloc 方法中释放它,如下所示:

- (void)dealloc {
   [mainView release], mainView = nil;
   [super dealloc];
}

然后在我的 中viewDidLoad,我正在分配它并将其添加为我的子视图,self.view如下所示:

- (void) viewDidLoad {

  mainView = [[UIView alloc] init];
  .
  .
  .
  [self.view addSubView: mainView];
}

现在我明白了,此时我mainView将有 3 个引用计数(一个来自 alloc,一个因为它是保留属性,第三个当我将它添加到时self.view),它的父控制器也将拥有它。现在,我的问题是,如果在将我的视图添加到 self.view 之后,我使用

[mainView release];

当我将释放发送到已释放的对象时,当我返回上一个视图时,我的应用程序崩溃了。现在我的问题是我如何在这里过度释放我的观点。我错过了什么,因为当我使用以下代码时它工作正常并且没有发生崩溃。

- (void) viewDidLoad {
  UIView *newView = [[UIView alloc] init];
  self.mainView = newView;
  [newView release];
  .
  .
  .
  [self.view addSubView: mainView];
}

我知道为什么第二个 viewDidLoad 方法有效,但我不知道为什么第一个会失败,我应该在将其添加到 self.view 后释放我的视图。对?

注意:我知道在第一个 viewDidLoad 中,我可以使用 autorelease 方法来释放分配给 ivar 的视图,它不会崩溃,但重点是我试图尽可能减少 autorelease 的使用。而且我根本没有使用ARC

我非常感谢您的解释和建议。

4

3 回答 3

3

从你的问题:

现在我明白了,此时我的 mainView 将有 3 个引用计数(一个来自 alloc,一个因为它的保留属性,第三个当我将它添加到 self.view 时)

您没有通过属性进行分配,而是直接分配给实例变量,因此没有保留;只有在 ARC 中,分配给实例变量的值才会保留。因此,请勿执行手动释放。

于 2013-01-16T03:58:35.557 回答
2

为了让您@property保留mainView,您应该将其用作self.mainView而不只是mainView. 如果您单独使用后者,它将不会保留它。基本上,如果你调用它,它就是调用一个在内部执行self.mainView = ...的 setter 方法。当你直接分配它时,它不会执行这个setter,也不会执行retain。mainView[mainView retain];

你应该这样试试

self.mainView = [[[UIView alloc] init] autorelease];
[self.view addSubView:self.mainView];

或如您的问题所示。

UIView *newView = [UIView alloc] init];
self.mainView = newView;
[newView release];
[self.view addSubView:self.mainView];

您也可以尝试将 ARC 用于您的项目。您的代码在 ARC 中将如下所示,

self.mainView = [[UIView alloc] init];
[self.view addSubView:self.mainView];

查看文档以获取更多详细信息。

于 2013-01-16T03:58:43.897 回答
2

在您的第一个 viewDidLoad 方法中,您不是指 self.mainView 仅 mainView 这就是它不保留的原因,为了保留属性工作,您必须使用 self.mainView 设置 mainView!

于 2013-01-16T03:59:00.250 回答