Iphone 我需要释放xib资源吗?

Iphone 我需要释放xib资源吗?,iphone,objective-c,cocoa-touch,Iphone,Objective C,Cocoa Touch,如果我有类似UILabel的东西链接到xib文件,我需要在视图的dealloc上发布它吗?我问的原因是因为我没有分配它,这让我觉得我也不需要释放它? 例如(在标题中): 在实施过程中: .... [lblExample setText:@"whatever"]; .... -(void)dealloc{ [lblExample release];//????????? } 相关:在某种意义上,您可以通过在IB中创建标签来分配标签 IB所做的是查看您的IBOutlet以及它们是如何定义

如果我有类似UILabel的东西链接到xib文件,我需要在视图的dealloc上发布它吗?我问的原因是因为我没有分配它,这让我觉得我也不需要释放它? 例如(在标题中):

在实施过程中:

....
[lblExample setText:@"whatever"];
....

-(void)dealloc{
    [lblExample release];//?????????
}

相关:

在某种意义上,您可以通过在IB中创建标签来分配标签

IB所做的是查看您的IBOutlet以及它们是如何定义的。如果您有一个类变量,IB将为某个对象分配一个引用,IB将为您向该对象发送一条retain消息

如果您使用的是属性,IB将使用您必须设置的属性值,而不是显式保留该值。因此,您通常会将IBOutlet属性标记为retain:

@property (nonatomic, retain) UILabel *lblExample;

因此,在以太情况下(使用或不使用属性),您应该在dealloc中调用release。

我在Apple文档中找到了我想要的内容。简而言之,您可以将对象设置为释放和保留的属性(或仅设置为@property、@synthesis),但对于UILabels之类的东西,您不必这样做:


作为Nib主视图子视图的任何IBOutlet都不需要释放,因为它们将在对象创建时发送自动释放消息。您需要在dealloc中释放的唯一IBOutlet是顶级对象,如控制器或其他NSObject。以上链接的Apple文档中都提到了这一点。

如果您遵循现在被认为是最佳实践的方法,您应该发布插座属性,因为您应该在set accessor中保留它们:

@interface MyController : MySuperclass {
    Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end


@implementation MyController

@synthesize uiElement;

- (void)dealloc {
    [uiElement release];
    [super dealloc];
}
@end
这种方法的优点是,它使内存管理语义明确明了,并且在所有nib文件的所有平台上都能始终如一地工作

注意:以下注释仅适用于3.0之前的iOS。对于3.0及更高版本,您应该在viewDidUnload中简单地将属性值置零

不过,这里需要考虑的一个问题是,当您的控制器可能会丢弃其用户界面并根据需要动态重新加载它时(例如,如果您有一个视图控制器,它从nib文件加载视图,但在请求时(比如在内存压力下)会释放它,并期望在再次需要视图时可以重新加载它)。在这种情况下,您希望确保当主视图被释放时,您也会放弃对任何其他门店的所有权,以便它们也可以被释放。对于UIViewController,您可以通过覆盖
setView:
来处理此问题,如下所示:

- (void)setView:(UIView *)newView {
    if (newView == nil) {
        self.uiElement = nil;
    }
    [super setView:aView];
}
不幸的是,这引发了另一个问题。由于UIViewController当前使用
setView:
accessor方法(而不是直接释放变量)实现其
dealloc
方法,因此
self.anOutlet=nil
将在
dealloc
中调用,并响应内存警告。。。这将导致
dealloc
中的崩溃

补救措施是确保在
dealloc
中出口变量也设置为
nil

- (void)dealloc {
    // release outlets and set variables to nil
    [anOutlet release], anOutlet = nil;
    [super dealloc];
}


如果您正确编写了setView:部分,则该部分是完全多余的。

如果您不在dealloc时释放它,则会增加内存占用


如果您没有将IBOutlet设置为属性,而只是将其设置为实例变量,则仍然必须释放它。这是因为在initWithNib时,内存将分配给所有IBOutlet。因此,这是一种特殊情况,即使您没有在代码中保留或分配任何内存,您也必须释放它。

@Soeren:我已经阅读了那篇文章,并且理解了它的内容。我的问题是关于在IB xib上实例化的对象,它没有涵盖这些对象。我从来没有真正创建或分配过标签,IB魔术就是这么做的。所以我需要知道的很简单:我需要释放它吗?这实际上是错误的。是否应该向顶级对象发送发布消息取决于您使用的平台以及文件所有者继承的类。例如,如果它继承自NSWindowController,则不需要释放它们。这是不正确的。如果您不使用属性(或实现您自己的访问器方法),那么您是否应该发布取决于您所处的平台以及您的超类是什么。例如,如果您从NSWindowController继承,您就不会释放。如果我们有一个retain属性,我们是否可以简单地说self.uiElement=nil来简化这个过程;在我们想要发布的所有地方,由于它是一个retain属性,它实际上应该正确地发布它,并将其设置为nil而没有问题,这是retain属性的优点之一
viewDidUnload
中,不在
setView:
中。只调用self.anOutlet=nil会更清楚在dealloc中。不应调用self.anOutlet=nil;在dealloc中。在dealoc中调用访问器是一种不好的做法。我完全不同意“在dealoc中调用访问器是一种不好的做法”,我经常这样做,这使代码更干净了10亿倍。你对此有参考资料吗?@Wil Shipley:几个苹果文档建议不要在init和dealloc方法中使用访问器。例如:-AFAICT,基本上,除了设置变量外,setter(以及在KVO下)还有副作用,如果您触发KVO通知,您可能会在对象解除分配后通知人们发送对象消息。事实上,我理解,这在3.0及更高版本中已经发生了变化。我们现在有了-viewDidUnload,这就是我们发布访问器的地方。
- (void)dealloc {
    // release outlets and set variables to nil
    [anOutlet release], anOutlet = nil;
    [super dealloc];
}
[anOutlet release], anOutlet = nil;