NSView *实例变量的Obj-C内存管理

时间:2011-01-08 21:58:32

标签: objective-c cocoa memory-management

我的自定义视图将子视图作为实例变量。 这是一个示例界面:

@interface MyCustomView : NSView {
    NSView *aSubview;
}

@end

然后,在.m文件中,我初始化aSubView并将其添加到自定义视图。

- (id)init
{
    self = [super initWithFrame:CGRectMakeFrame(0.0, 0.0, 320.0, 480.0);
    if (self) {
        aSubview = [[NSView alloc] initWithFrame(0.0, 0.0, 100.0, 100.0);

        [self addSubview:aSubview];
    }
    return self;
}

我应该在哪里发布aSubView

-dealloc方法中?

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

或者在将其添加到-init方法的自定义视图后直接?

- (id)init
{
    [...]
    [self addSubview:aSubview];
    [aSubview release];
    [...]
}

哪一个是最佳实施?

3 个答案:

答案 0 :(得分:2)

您的代码中有两个保留,用于不同的目的。最好将它们分开。

保留#1

aSubview = [[NSView alloc] initWithFrame(0.0, 0.0, 100.0, 100.0);隐含第一个保留。由于aSubview是一个实例变量,并且您似乎希望在初始化程序运行后将aSubview作为对视图的有效引用,因此隐含的保留将由{{1}平衡在release

保留#2

当添加到视图层次结构中时,您的视图实例将保留在其子视图的任何视图中。在这种情况下它是dealloc是无关紧要的。只要视图是视图层次结构的一部分,该保留就会生效。删除后,它将被释放。


这两者是对象寿命的正交实现。将它们分开使您的代码不那么脆弱。

例如,如果在某个未来版本中,您偶尔会从视图层次结构中删除视图,并希望稍后再将其粘贴 - 最终显示/隐藏,如果您愿意 - 那么保留#1 上面会保留它。

同样地,如果你有一天想要忘记当前的视图,但用另一个视图替换它,你可以简单地做:

self

在这种情况下,上面的保留#2 将使旧视图在视图层次结构中保持活动状态。

答案 1 :(得分:1)

我说你应该在将它添加到视图后直接发布“aSubview”。 (即:一旦保留在其他地方。)

但是,我也说过将“aSubview”作为实例变量没有任何价值 - 它应该只是init方法中的局部变量。

答案 2 :(得分:1)

我更喜欢dealloc因为当你的对象包含其他对象时,你必须在你自己dealloc时释放它们。