【问题标题】:Difference between presentModalViewController and pushViewController regarding memory managementpresentModalViewController 和 pushViewController 关于内存管理的区别
【发布时间】:2013-01-14 10:17:09
【问题描述】:

虽然我已经解决了这个问题。我真的需要有人向我解释它为什么有效。

我有一个 UINavBar,它有一个自定义的 UIView 作为可见的 ViewController。我创建了一个自定义按钮来代替导航栏的标题视图并将其设置为 autorelease(我正在自定义现有的非 ARC code):

- (void)loadView {
    ..  

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button addTarget:self
               action:@selector(presentEmailThreadList)
     forControlEvents:UIControlEventTouchDown];
    [button setTitle:[NSString stringWithFormat:@"1 of %d",self.numThreads] forState:UIControlStateNormal];
    button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);

    self.navigationItem.titleView = [button autorelease];
}

当我以模态方式呈现视图时,此代码有效,即:

[self presentModalViewController:emailThreadListVC animated:YES];

但如果我尝试将其推送到导航堆栈,则会出现EXC_BAD_ACCESS 错误,然后单击新 VC 上的“后退按钮”:

[self.navigationController pushViewController:emailThreadListVC animated:YES];

特别是在UINavigationItemTitleView 处崩溃:

我得出结论,当我尝试返回原始 VC 时,titleView 不再存在,这意味着当我将 VC 压入堆栈顶部时,autorelease 确实减少了 titleView 上的引用计数,但是当我以模态方式推送 VC 时,它不会减少引用计数。

知道为什么吗?

【问题讨论】:

  • 请记住,模态窗口是模态的 - 系统知道您会在某个时候回来,所以这可能是它保持引用计数的原因。
  • 您能否展示一下您是如何创建button(关于内存管理)的?
  • @sergio 确定刚刚更新了代码(虽然我认为没有什么特别之处)

标签: objective-c uiviewcontroller automatic-ref-counting modal-dialog pushviewcontroller


【解决方案1】:

问题出在这里:

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
...
self.navigationItem.titleView = [button autorelease];  <-- DOUBLE AUTORELEASE

buttonWithType 已经返回了一个自动释放的对象,所以你不需要再次显式地自动释放它。

为什么它在您使用 presentViewController 时有效是另一个问题。我认为这归结为两种情况的不同时间。

【讨论】:

    猜你喜欢
    • 2011-12-24
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 2011-04-13
    • 1970-01-01
    • 2011-08-22
    相关资源
    最近更新 更多