2010-06-02 66 views
4

我很难在UIViewController中的几个方法,但首先我会说我认为他们的意思(忽略接口生成器,因为我不使用它):iPhone开发 - viewDidUnload子视图

-init:初始化不需要在低内存情况下释放的非视图相关的东西(即不是不容易重新创建的对象或对象)。
-loadView:创建视图设置[self view]属性。
-viewDidLoad:创建所有其他视图元素
-viewDidUnload:在-viewDidLoad中创建的发布对象。
didReceiveMemoryWarning:低内存的情况,释放不必要的东西,如缓存的数据,如果这个视图没有超级视图然后[super didReceiveMemoryWarning]将继续释放(卸载)视图,并呼吁-viewDidUnload
-dealloc:释放一切
-viewWillAppear:-viewDidAppear:-viewWillDisappear:-viewDidDisappear:不言自明的,没有必要,除非你想回应(做某事)这些事件。

我不确定一些事情。首先,苹果文档说,当调用-viewDidUnload时,视图已经发布并设置为零。

  1. 请问-loadView会再次调用以重新创建视图吗?
  2. 我在-viewDidLoad中创建了一些东西,我没有制作ivar/property,因为没有必要,它会被视图保留下来(因为它们是子视图)。所以当视图被发布时,它也会释放这些,对吧?当视图发布时,它是否会发布其所有子视图?因为我在-viewDidLoad中创建的所有对象都是子视图[self view]。所以如果他们已经发布了,为什么要在-viewDidUnload再次发布它们?我可以理解在这些方法中加载和卸载视图时必要的数据,但正如我所问,为什么释放子视图,如果它们已经发布?

编辑:阅读其他问题后,我想我可能会得到它(我的第二个问题)。在我只使用局部变量的情况下,进行分配,使其成为子视图并释放,其保留计数为1(将其作为子视图添加),因此视图释放时也是如此。现在对于ivars指向它们的视图元素,我没有使用属性,因为没有外部类需要访问它们。但现在我认为这是错误的,因为在这种情况下:

// 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; 
} 

在这种情况下,该标签将被发送-release消息后,它被释放,因为伊娃没有保留它(因为它不一个属性)。但是对于一个财产,保留数将是两个:保留它的视图和财产。然后在-viewDidUnload它将被释放。所以最好总是使用这些东西的属性,我说得对吗?或不?

回答

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没有明确保留标签,但是您仍然拥有它,因为您已分配它。这是可可内存管理的基本规则之一:alloc +1,retain +1,release -1,autorelease -1稍后。

实施例:

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

这将是一个泄漏,因为标签的alloc期间获得一个1和另一个1在设定器用于foo属性生成。阅读Cocoa内存管理指南或Scott Stevenson’s Objective-C tutorial。 Cocoa的内存管理非常简单,经过一番思考后,你应该在所有情况下都非常舒适。

+0

谢谢,我明白了。但是,我是否正确地使用属性,我编辑的文章的最后部分? – mk12 2010-06-02 15:13:54

+0

什么我问的是只是为了证实这一点:除了卸载,您将在'-viewDidLoad',重新创建数据'-viewDidUnload'是解除性('[个体经营的setProperty:无]'),其仍保留的子视图' [self view]','[self view]'已经发布,所以可以解除分配。我对吗? – mk12 2010-06-02 15:17:17

+0

但我认为那里的例子有代码不起作用?因为成员变量myLabel从不保留UILabel(只有视图),但它仍然在'-viewDidUnload'中释放它。或者你是在谈论我之后描述的内容?我想要决定的是我应该总是使用像这样的东西(我需要一个成员变量)的属性? – mk12 2010-06-02 15:26:33