2009-08-09 102 views
1

我一直在尝试一些来自Erica Sadun的书“iPhone Developer's Cookbook”的视图代码,并发现了一些我不明白的代码。下面是一个的loadView方法的代码:为什么iPhone Developer's Cookbook的这段代码有效?

- (void)loadView 
{ 
    // Create the main view 
    UIView *contentView = [[UIView alloc] initWithFrame: 
     [[UIScreen mainScreen] applicationFrame]]; 
    contentView.backgroundColor = [UIColor whiteColor]; 
    self.view = contentView; 
    [contentView release]; 

    // Get the view bounds as our starting point 
    CGRect apprect = [contentView bounds]; 

    // Add each inset subview 
    UIView *subview = [[UIView alloc] 
     initWithFrame:CGRectInset(apprect, 32.0f, 32.0f)]; 
    subview.backgroundColor = [UIColor lightGrayColor]; 
    [contentView addSubview:subview]; 
    [subview release]; 
} 

我的问题是,为什么她释放内容查看,但随后在[contentView addSubview:subview]再次使用它?有self.view = contentView保留contentView?

+0

这看起来不对。 'contentView'不会在方法结束之前被释放,所以这可能不会导致任何问题,但我无法想象为什么你会故意用这种方式构建它。 – kubi 2009-08-09 00:33:51

+0

不是。对self.view的赋值保留了contentView,所以在创建对象时最近可以得到它。这是故意构建的,因为(在Cocoa范例中)视图控制器保留视图是有意义的。 – 2009-08-09 15:40:31

回答

7

如果你的UIViewController的文档看,你会看到视图属性被声明为:

@property(nonatomic, retain) UIView *view;

这意味着,当您使用的setView:方法(或者在=的左边使用.view),那么你传入的任何值都将被保留。所以,如果你通过代码,并期待在保留数,你会得到这样的:

- (void)loadView { 
    // Create the main view 
    UIView *contentView = [[UIView alloc] initWithFrame: 
      [[UIScreen mainScreen] applicationFrame]]; //retain count +1 
    contentView.backgroundColor = [UIColor whiteColor]; //retain count +1 
    self.view = contentView; //retain count +2 
    [contentView release]; //retain count +1 

    // Get the view bounds as our starting point 
    CGRect apprect = [contentView bounds]; 

    // Add each inset subview 
    UIView *subview = [[UIView alloc] 
      initWithFrame:CGRectInset(apprect, 32.0f, 32.0f)]; 
    subview.backgroundColor = [UIColor lightGrayColor]; 
    [contentView addSubview:subview]; 
    [subview release]; 

}

我想说的是,真正有趣的事情,那就是释放内容查看后,我们仍然可以发送消息给它,因为生活在contentView指针末尾的对象仍然存在(因为它通过调用setView :)来保留)。

+1

这是正确的,但我个人避免这种风格/模式 - 如果在某个时候你决定改变该属性从'retain'到'assign',那么这段代码将自发地开始崩溃。当然,这不是UIViewController.view属性的问题,但是对于你自己的属性,它要求在路上遇到麻烦。 – 2009-08-09 01:03:27

+1

是的,这正是它工作的原因,它是一种可怕的形式。一旦你释放一个特定的参考,你不应该再次使用它,这是容易出错的。该版本应该移动到最后,否则contentView的所有外观应该更改为self.view。 – 2009-08-09 02:47:48

+0

它并不真正符合风格,除非“认为有害”是一种风格。 – Amagrammer 2009-08-09 04:23:57

0

如果你声明你的属性像这样 @property(nonatomic,retain)... TheN yes属性在分配时被保留。这可能是发生了什么事情

+0

制定一个明确正确的答案并避免即时通讯式缩写可能有助于避免将来降价。 (我没有downvote,我只是说...) – 2009-08-09 15:44:24

+0

我知道,但从iPhone输入响应很困难,当我写出最低限度,并且不能很好地表达编码时,但我认为这个答案将有助于 的反正,所以我发布它 – Daniel 2009-08-09 16:23:19