【问题标题】:Is this code over releasing?这段代码是否过度发布?
【发布时间】:2013-02-20 16:31:19
【问题描述】:

我找不到问题出在哪里,但是这段代码崩溃了。我是否过度释放任何对象?

settings = [[SettingsViewController alloc] initWithNibName:@"SettingsController" bundle:nil];
settings.hidesBottomBarWhenPushed = YES;

NSArray * arrayWithRootController = [[NSArray alloc] initWithObjects:settings, nil];
[(UINavigationController*)([self.tabBar.viewControllers lastObject])setViewControllers:arrayWithRootController];
[arrayWithRootController release];
[settings release];

如果我删除该行

[settings release];

应用程序不会崩溃。但我很确定它是正确的。问题可能出在其他地方吗?

有什么想法吗?非常感谢

【问题讨论】:

  • 您能发布崩溃的详细信息吗?该错误将非常有用。
  • @user1394965 你错了! iOS6 在内存管理方面没有任何改变。我相信你已经把它和自动引用计数混为一谈了。 (顺便说一句,iOS4/5 也可以使用!)
  • 如果 UINavigationController 保留其视图控制器,则此代码看起来正确。你可以通过使用 NSArray 工厂方法 -arrayWithObject: 来简化一些事情,因为结果是自动释放。
  • viewControllers 是根据 Apple 定义为副本的属性
  • 是否有充分的理由折磨自己,或者您只是想了解前 ARC 时代?

标签: ios cocoa-touch release


【解决方案1】:

你在这个 sn-p 中并没有过度释放,但显然有些地方是不对的。将根视图控制器添加到数组将保留它,但仅限于数组的生命周期。当数组死亡时,其中的所有对象也会被释放(我猜这里发生了什么)。

尝试几件事: 首先,确保将数组放在您认为自己所在的位置:

[(UINavigationController*)([self.tabBar.viewControllers lastObject])setViewControllers:arrayWithRootController];

你期望[self.tabBar.viewControllers lastObject] 是什么?您确定这是您要分配新数组的位置吗?如果接收者无效,您的数组将不会保留在您的下一行,这意味着视图控制器也将被释放。

我不熟悉您的架构,但您似乎正在将一组视图控制器分配给视图控制器。 self.tabBar 是一个导航控制器,你可以在上面调用setViewControllers。但是self.tabBar.viewControllers lastObject...嗯,大概这是一个视图控制器,但不一定是导航控制器,它可能不会响应 setViewControllers(在这种情况下它应该崩溃,除非它是 nil,我猜它可能是)。

最后,尝试使用 Instruments 工具 Zombies 看看您是否可以查明意外发布的来源。

【讨论】:

  • 是的,我将数组放在正确的位置,我尝试添加另一个视图控制器而不是“设置”并且它没有崩溃。问题在设置对象中是 100% 确定的
  • [UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] 就是对象的引用计数达到-1的方法
  • 看起来您在 XIB 中创建了一些界面。你在某处有一个 UITableViewController 对象吗?相关属性是否确定为强/保留?
猜你喜欢
  • 2011-10-04
  • 1970-01-01
  • 2012-08-14
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多