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

Posted

技术标签:

【中文标题】iOS 应用程序在释放保留属性时崩溃【英文标题】:iOS App Crashes while releasing a retained property 【发布时间】:2013-01-16 03:52:36 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

根据您的问题:

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

你不是通过属性赋值而是直接赋值给实例变量,所以没有retain;只有在 ARC 中,分配给实例变量的值才会保留。所以,不要执行手动释放。

【讨论】:

【参考方案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了解更多详情。

【讨论】:

非常感谢,所以在不使用 ARC 的情况下避免自动释放的唯一方法是我在第二个 viewDidLoad 方法中的做法? @VikSingh,是的,你是对的。这就是我们过去在非 ARC 中所做的方式。事实上,我们使用了自动释放。如果您觉得我的上述解释有帮助,请采纳。【参考方案3】:

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

【讨论】:

以上是关于iOS 应用程序在释放保留属性时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS14 上释放 wkwebview 时,发送手势事件导致崩溃

由于 NSDictionary 自动释放,应用程序在 iOS7 中崩溃,但在 8 和 9 中没有

iOS Cordova 应用程序在恢复时崩溃

设置自定义视图的 alpha 属性时,iOS 应用程序崩溃

iOS 9 的点播资源可以永久保留吗?

使用点语法设置保留属性时使用自动释放?