开发者

Obj-C memory management for an NSView * instance variable

开发者 https://www.devze.com 2023-02-03 18:35 出处:网络
My custom view has a subview as an instance variable. Here is a sampl开发者_开发技巧e interface:

My custom view has a subview as an instance variable. Here is a sampl开发者_开发技巧e interface:

@interface MyCustomView : NSView {
    NSView *aSubview;
}

@end

Then, in the .m file, I initialize aSubView and add it to the custom view.

- (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;
}

Where should I release aSubView?

In the -dealloc method?

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

Or directly after adding it to the custom view in the -init method?

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

Which one is the best implementation?


There are two retains in your code, serving different purposes. It is best to keep them separate.

Retain #1

The first retain is implied by aSubview = [[NSView alloc] initWithFrame(0.0, 0.0, 100.0, 100.0);. Since aSubview is an instance variable and you seemingly want to keep aSubview around as a valid reference to the view after the initializer has run, it makes sense that the implied retain would be balanced by a release in dealloc.

Retain #2

When added to the view hierarchy, your view instance will be retained by whatever view it is a subview of. That it is self in this case is irrelevant. As long as the view is a part of the view hierarchy, that retain will be in effect. When it is removed, it will be released.


The two are orthogonal realizations of object lifespan. Keeping them separate makes your code less fragile.

For example, if in some future version you were to occasionally remove the view from the view hierarchy with a desire to stick it back later -- the ultimate show/hide, if you will -- then retain #1 above will keep it around.

Similarly, if you were to someday want to forget about the current view, but replace it with a different one, you could simply do:

[aSubview release];
aSubview = [[.... alloc] ... init ... ];

And, in this case, retain #2 above will keep the old view alive in the view hierarchy.


I'd say that you should release "aSubview" directly after you add it to the view. (i.e.: As soon as its been retained elsewhere.)

However, I'd also say that there's no value in having "aSubview" as an instance variable - it should just be a local variable within your init method.


I would prefer in the dealloc because When your object contains other objects, you must free them whenever you yourself dealloc.

0

精彩评论

暂无评论...
验证码 换一张
取 消