iPhone dev - viewDidUnload子视图

时间:2010-06-02 15:05:05

标签: iphone objective-c memory-management uiviewcontroller

我很难在UIViewController中找到一些方法,但首先我会说出我认为它们的意图(忽略界面构建器,因为我没有使用它):

-init:初始化不需要在低内存情况下释放的非视图相关内容(即不能轻易重新创建的对象或对象)。
-loadView:创建视图集[self view]属性 -viewDidLoad:创建所有其他视图元素
-viewDidUnload:释放在-viewDidLoad中创建的对象 didReceiveMemoryWarning:低内存情况,释放不必要的内容,如缓存数据,如果此视图没有超级视图,则[super didReceiveMemoryWarning]将继续释放(卸载)视图并调用{{1 }}。
-viewDidUnload:释放所有内容 -dealloc-viewWillAppear:-viewDidAppear:-viewWillDisappear:不言自明,除非您想对这些事件做出回应(做某事),否则没有必要。

我不确定几件事。首先,Apple文档说当调用-viewDidDisappear:时,视图已经被释放并设置为nil。

  1. 稍后会再次调用-viewDidUnload来重新创建视图吗?
  2. 我在-loadView创建了一些我没有制作ivar /属性的东西因为没有必要而且它将被视图保留(因为它们是它的子视图)。因此,当视图发布时,它也会释放它们,对吧?视图发布后,它会释放所有子视图吗?因为我在-viewDidLoad中创建的所有对象都是-viewDidLoad的子视图。因此,如果他们已经被释放,为什么要在[self view]中再次发布它们?我可以理解在这些方法中加载和卸载视图时所需的数据,但就像我问的那样,为什么要释放子视图,如果它们已经发布了呢?
  3. 编辑:在阅读其他问题之后,我想我可能已经得到了它(我的第二个问题)。在我只使用局部变量,分配它,使其成为子视图和释放的情况下,它将保留计数为1(从将其添加为子视图),因此当视图被释放时它也是如此。现在对于ivars指向它们的视图元素,我没有使用属性,因为没有外部类需要访问它们。但现在我认为那是错的,因为在这种情况下:

    -viewDidUnload

    在这种情况下,标签将在解除分配后发送// MyViewController.h @interface MyViewController : UIViewController { UILabel *myLabel; } // MyViewController.m . . . - (void)viewDidLoad { myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 10)]; [myLabel setText:@"Foobar"]; [[self view] addSubview:myLabel]; } - (void)viewDidUnload [ // equivalent of [self setMyLabel:nil]; without properties [myLabel release]; myLabel = nil; } 消息,因为ivar没有保留它(因为它不是属性)。但是对于一个属性,保留计数将是两个:保留它和属性的视图。那么在-release中它将被解除分配。所以最好总是使用属性来做这些事情,对吗?或不?

1 个答案:

答案 0 :(得分:2)

  

稍后会再次调用-loadView来重新创建视图吗?

是的,只要有人访问view属性。

  

发布视图后,它会释放所有子视图吗?

至于标签和以后不需要的东西,通常的方法是在将它们附加到视图后简单地释放它们:

UILabel *foo = [[UILabel alloc] init…];
[self.view addSubview:foo];
[foo release];

在这种情况下,当视图被取消分配时,标签将被释放。


您的示例中的内存管理很好。当您alloc标签时,其retainCount跳转为1,视图会保留该标签(retainCount = 2),然后视图将被取消分配并释放标签(rc = 1)然后你最终自己发布标签(rc = 0,dealloc)。

为了使事情更加清晰 - 变量myLabel未明确保留标签,但您仍然拥有它,因为您已经分配了它。这是Cocoa内存管理的基本规则之一:alloc +1,retain +1,release -1,autorelease -1。

示例:

@property(retain) UILabel *foo;
self.foo = [[UILabel alloc] init…];

这将是一个泄漏,因为标签在alloc期间获得+1,而在为foo属性生成的setter中获得+1。阅读Cocoa Memory Management Guide或Scott Stevenson’s Objective-C tutorial。 Cocoa中的内存管理非常简单,经过一番思考后,你应该在所有情况下都非常舒服。

相关问题