使用loadNibNamed:方法时是否需要释放IBOutlets?

时间:2008-12-19 23:35:47

标签: iphone objective-c

我有一个.xib文件,其中包含一个UIView和2个UILabel子视图,这些子视图链接到一个名为Note的类,其中适当地分配给每个标签的出口,该类的定义包含以下内容。

@interface Note : UIView {
    IBOutlet UILabel *time;
    IBOutlet UILabel *content;
}

我正在使用以下代码

构建它
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"Note" owner:self options:nil];
note = [nibViews lastObject];
[self addSubview:note];

现在,在我的Note类dealloc阶段,我没有发布任何时间或内容,但我想知道我是否应该?

- (void)dealloc {
    [super dealloc];
}

我假设我没有,因为我没有在代码中的任何地方明确地保留这些对象,并且我没有将这些对象合成到getter / setter中。但是我不知道nib是否能够知道我是否应该在我的dealloc阶段发布这些内容?

5 个答案:

答案 0 :(得分:14)

即使您编写或合成访问者方法,也应该发布IBOutlet。 NIB生命周期文档说尽管未归档的对象最初设置为自动释放,但当UIKit挂钩所有IBOutlet连接绑定时,它们的保留计数会增加1。因此,您需要在完成后通过释放手动递减。

UIKit做这件事并不明显,所以你可能会认为你可以放弃setter / getter方法,并相信一切都是自动释放的。但事实并非如此。

请注意,Interface Builder模板显式释放任何IBOutlet,因此您应该同样对待任何添加的内容。

答案 1 :(得分:2)

这对iPhone来说是正确的;但是在Mac上它不正确。

但是,您可能需要重新编写此代码。假设视图将是从笔尖加载的最后一个对象是不安全的。我建议您将它连接到视图控制器中的“注释”插座,或者扫描列表以查找作为Note子类的对象。 (如果您正在加载多个Notes并使用outlet选项,请确保在加载另一个之前添加一个Note。)

答案 2 :(得分:0)

你需要释放它。参见

“然而,在重建对象层次结构时,UIKit使用setValue:forKey:方法重新建立对象之间的连接,该方法使用可用的setter方法,或者如果没有可用的setter方法,则默认保留该对象。”在Nib Object Retention

换句话说,因为您没有将这些条目指定为@property(隐式声明一个setter),或者直接提供了一个setter,所以没有可用的setter方法,并且本段的最后部分适用 - 该对象默认保留。

您应该在dealloc()方法中使用

将所有IBOutlet设置为nil
self.outletName = nil;

如果没有定义setter,那么setValue将自动释放旧值(如果在线程中运行,请确保你有一个NSAutoreleasePool)。如果定义了setter,它将执行您定义的任何行为。无论哪种方式,设置为nil将完全正确的事情,并确保您没有内存泄漏。不要这样做

outletName = nil;

这将直接设置成员变量,并绕过调用setValue。

有关更多详细信息,请参阅NSObject setValue:forKey的文档。

运行性能工具(泄漏)不会显示泄漏,但您可以通过查看当前运行的已分配内存总量来验证是否存在实际泄漏。

cf The Airsource - Memory Management and NIBs

答案 3 :(得分:0)

除非您将IBOutlets声明为属性并将其合成为ivars,否则您将无法将它们从内存中取出:

@interface Note : UIView {
    IBOutlet UILabel *time;
    IBOutlet UILabel *content;
}

@property (nonatomic, retain) IBOutlet UILabel *time;
@property (nonatomic, retain) IBOutlet UILabel *content;

@end


@implementation Note
@synthesize time, content;

// your methods

- (void)dealloc {
     [time release], time = nil;
     [content release], content = nil;
     [super dealloc];
}

@end

答案 4 :(得分:-6)

我相信你是对的。有关详细信息,请参阅下面的文档链接。

文档: