【问题标题】:UINavigationViewController memory releasingUINavigationViewController 内存释放
【发布时间】:2009-08-01 03:47:15
【问题描述】:

首先,自从我在阅读了一篇关于内存在 obj-C 中如何表现的文章后开始将“self”放置在任何地方以来,我从未在我的应用程序中看到如此多的内存问题。现在,我遇到了各种各样的问题(揭示了我编码的草率)。诚然我是 Objective-C 的新手,我承认我以前从未遇到过这么多内存管理问题。但我认为这需要练习才能习惯。

现在,我的问题。

我有一个类接口属性 (self.todoCreate),它包含对上述控制器的引用。按下按钮即可导航到此控制器。

@property (nonatomic, retain) TodoTaskCreateController *todoCreate;

下面的代码是导致导航视图变化的sn-ps:

TodoTaskCreateController *viewController = [[TodoTaskCreateController alloc] 
                   initWithNibName:@"TodoTaskCreateController"
                            bundle:[NSBundle mainBundle]];

self.todoCreate = viewController;
[viewController release];
// slide-in todoCreate controller.  
if (self.navigationController != nil && self.todoCreate != nil) {
    [self.navigationController pushViewController:self.todoCreate animated:YES];
}

所以这是我的问题:

我第一次运行它就可以了。 进入第二个视图屏幕后,我导航回主视图。 如果我第二次尝试再次导航,则应用程序崩溃,就在 self.todoCreate 被分配 viewController 的位置。

请注意,在主视图的viewDidAppear 方法中,我调用[self.todoCreate release]

谁能解释一下?

PS - 难怪有这么多 iPhone 应用程序随机崩溃。

【问题讨论】:

    标签: objective-c memory-management uiviewcontroller


    【解决方案1】:

    todoCreate 是一个属性,这意味着当您为其赋值时,它会调用一个名为 setTodoCreate 的方法,该方法类似于:

    - (void) setTodoCreate:(Foo*) newVal
    {
        [todoCreate release]; // release the previous object
        todoCreate = [newVal retain]; // point to new object, and also retain it
    }
    

    现在您的viewDidAppear 方法正在释放self.todoCreate,此时todoCreate 的保留计数为0。当您创建一个新的TodoTaskCreateController 并将其分配给self.todoCreate 时,会执行另一个release,但是这次是在保留计数为 0 的对象上。

    您应该使用self.todoCreate = nil,而不是[self.todoCreate release]

    您可能也不应该不断地破坏和创建您的TodoTaskCreateController

    您对应用程序崩溃的评论很可能是由于开发人员没有测试他们的应用程序以查看它是否正确处理内存警告。在模拟器中,有一个菜单选项可以模拟这一点,您的应用程序应该在其所有视图中“幸存”警告。

    【讨论】:

      【解决方案2】:

      我不会很快与之交谈,但看来我已经解决了崩溃,只需将 viewController 添加到自动释放池中,然后删除其释放的所有手动事件。

      现在我的 createTodo 的 @property 是否定义为 (nonatomic, retain) 而不是 (nonatomic, assign)?

      【讨论】:

      • 如果你用retain属性做self.todoCreate = <something>,旧值将被释放;如果您对 assign 属性执行相同操作,则不会释放旧值。
      • 等一下,我认为它的行为与您描述的完全相反。由于retain 增加了引用计数,用retain 描述的属性不会被释放吗?再一次,就在我以为自己掌握了窍门的时候,这样的事情动摇了我对它的理解。非常令人沮丧。
      猜你喜欢
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      • 2013-12-05
      • 2015-04-22
      • 2011-01-17
      • 2021-12-23
      • 2017-06-29
      相关资源
      最近更新 更多