iOS应用程序在释放保留属性时崩溃

时间:2013-01-16 03:52:37

标签: ios objective-c properties uikit autorelease

我有一个问题。这个问题可能有一个非常简单的解决方案,但我还没有弄清楚。如果我使用属性@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
[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

我真的很感激解释和建议。

3 个答案:

答案 0 :(得分:3)

从你的问题:

  

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

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

答案 1 :(得分:2)

为了让@property保留mainView,您应该将其用作self.mainView,而不仅仅是mainView。如果单独使用后者,则不会保留它。基本上,如果您致电self.mainView = ...,则会调用mainView的setter方法,该方法在内部执行[mainView retain];。当你直接分配它时,它不会执行这个setter并且不会执行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];

查看the documentation了解详情。

答案 2 :(得分:2)

在你的第一个viewDidLoad方法中你没有引用self.mainView只有mainView这就是为什么它不被保留,为了保留属性你需要使用self.mainView设置mainView!