views:

77

answers:

4

Basically I have this scenario going on:

//in interface header 
@property(nonatomic,retain)OtherClass *otherClass;

//implementation
- (id)initWithOtherClassInstance:(OtherClass*)otherClass
{ 
    if (self != [super init])
        return self;

         self.otherClass = otherClass;

    return self;
}

- (void)dealloc
{
    //Do I need to release otherClass ?
    [otherClass release];

    [super dealloc];
}

I'm wondering whether I should release an instance variable on which not explicitly alloc, new or copy was called? The memory management guides say I shoud not, but what I'm worrying about is that self.otherClass = otherClass would retain the instance variable and thus cause a leak when I would decide to not release it in the dealloc method.

Moreover releasing the instance variable in the dealloc method does not generate an exception, which it would in case it was overreleased.

Does my reasoning here make any sense, and what is the best thing to do in a case like this ?

A: 

You are doing this right, the rule you mentioned is the 'create' rule. You still need to match all your retains with releases as well.

Joshua Weinberg
A: 

Note that

self.otherClass = otherClass

is the same as

[self setOtherClass:otherClass]

The default implementation on setOtherClass: looks like

- (void) setOtherClass:(OtherClass*)other
{
  [other retain];
  [otherClass release];
  otherClass = other;
}

As you can see, it retains the object, so you have to release it somewhere.

If you don't like explicit release without explicit alloc, new or copy, then you can do the next in dealloc:

- (void) dealloc
{
  [self setOtherClass:nil];
  [super dealloc];
}
Yuras
Actually the default implementation of a property is simply to assign the instance variable. The property needs to be a *retain* property for the implementation to look like your setter.
JeremyP
By the way, your setter has a bug in it. If the argument other is the same as otherClass, you might be assigning a dealloc'd pointer.
JeremyP
+1  A: 

Yes you do need to release this, as other answers suggest. But I find that explicitly calling [foo release] on an ivar that you retained via property setter to be a little unbalanced. I prefer setting self.otherClass = nil; in these scenarios.

Of course under the hood it will do a release for you, but it just looks more balanced and clean.

Ben Scheirman
This gets into the religious debate about using property accessors in dealloc.
Joshua Weinberg
It's not a religious debate. Apple says not to. It is unquestionably preferred in Cocoa to release instead of using an accessor in `dealloc`. I don't personally like the way it is, but I don't see much room for disagreement when the docs specifically say one way or the other.
Chuck
A: 

Your init method is wrong. You need to assign the result of [super init] to self.

Other than that, assuming that self.otherClass is a retain property, what you have done is sort of OK. If you insist on using the property in -init you should assign the property to nil in dealloc, as Ben says, because then whether the property is assign, retain or copy, the right thing will happen.

However,

it is recommended that you do not use accessors in the -init and -dealloc methods. This is because subclasses may override them to do things you don't expect and KVO observers might get notified in dealloc. So you should probably just set and retain the ivar in init and release it in dealloc.

JeremyP