首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iPhone dev - viewDidUnload子视图

iPhone dev - viewDidUnload子视图
EN

Stack Overflow用户
提问于 2010-06-02 15:05:05
回答 1查看 1.4K关注 0票数 4

我很难在UIViewController中找到几个方法,但首先我要说明我认为它们的目的是什么(忽略接口生成器,因为我没有使用它):

-init:初始化不需要在低内存情况下释放的与视图相关的内容(即不能轻松重新创建的对象或对象)。

-loadView:创建视图,设置[self view]属性。

-viewDidLoad:创建所有其他视图元素

-viewDidUnload:释放在-viewDidLoad中创建的对象。

didReceiveMemoryWarning:在内存不足的情况下,释放不必要的东西,比如缓存的数据,如果这个视图没有超级视图,那么[super didReceiveMemoryWarning]将继续释放(卸载)视图并调用-viewDidUnload

-dealloc:发布所有内容

-viewWillAppear:-viewDidAppear:-viewWillDisappear:-viewDidDisappear:不言自明,除非你想对这些事件做出反应(做点什么),否则没有必要.

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

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

编辑:在阅读了其他问题之后,我想我可能已经理解了(我的第二个问题)。在我只使用局部变量、分配它、使它成为子视图并发布的情况下,它的保留计数为1(通过将其添加为子视图),所以当视图被释放时也是如此。现在,对于带ivars指向它们的视图元素,我没有使用属性,因为没有外部类需要访问它们。但现在我认为这是错误的,因为在这种情况下:

代码语言:javascript
复制
// 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消息被释放后发送给它,因为ivar没有保留它(因为它不是属性)。但是对于一个属性,保留计数是两个:保留它的视图和属性。因此,在-viewDidUnload中,它将被取消分配。所以最好总是用属性来做这些事情,对吗?还是不想?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-06-02 15:12:35

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

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

当视图发布时,它会发布所有的子视图吗?

是。

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

代码语言:javascript
复制
UILabel *foo = [[UILabel alloc] init…];
[self.view addSubview:foo];
[foo release];

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

在您的示例中,内存管理是可以的。当您alloc标签,它的retainCount跳到1,视图保留它(retainCount = 2),然后视图被解除分配并释放标签(rc = yourself 1),然后您最终自己释放标签(rc = 0,dealloc)。

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

示例:

代码语言:javascript
复制
@property(retain) UILabel *foo;
self.foo = [[UILabel alloc] init…];

这将是一个漏洞,因为标签在alloc期间获得+1,在为foo属性生成的setter中获得另一个+1。阅读Cocoa内存管理指南或斯科特·史蒂文森的目标-C教程。Cocoa中的内存管理非常简单,经过一段时间的反复思考,您在所有情况下都应该非常舒适。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2958973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档