views:

1798

answers:

2

I have seen sample source code around that uses different ways of releasing/dealloc'ing objects, so I was wondering which way is deemed the "best" one. A few options on -dealloc:

1) Release objects

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

2) Set objects to nil

- (void)dealloc {
    self.obj1 = nil;
    self.obj2 = nil;
    [super dealloc];
}

3) De-allocate objects directly

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

Which way is the best one? Pros and cons for each?

+8  A: 

Method 1 is the only recommended method. It's also good practice to set them to nil AFTER you've released them.

Method 2 only works for properties that manage their own object/value retaining, so it's not universally applicable. And if you implement your own setter method that performs other actions when the property changes, you may get undesired side effects by calling it in [dealloc].

Method 3 violates the reference-counting principle because it will deallocate the objects even if something else has a [retain] hold on them, so when the other objects access them next, your program will crash. You're never supposed to call [dealloc] directly -- let the runtime call it when the last owner calls [release].

Marco
Agreed. Method 1 is best. Method 3 is pretty much guaranteed to crash your app. And Method 2, like Marco said, can cause unintended side effects. The purpose of the dealloc method is to release any objects you're holding. Calling release on those objects is the only thing that makes sense.
Alex
I use method 2 whenever I'm going property-heavy and targeting the modern runtime (where I don't even declare any ivars directly). Granted, this is only because gcc doesn't yet allow you to access the autogenerated ivars directly (though that's coming).
Kevin Ballard
+1  A: 

If obj1 and obj2 are properties using @synthesize-d accessors, then method 1 and method 2 are equivalent. If either of those two conditions is not true then the effect is rather different. If they're not properties, then method 2 just sets the pointers to nil without doing anything that would deallocate the objects. And if they are properties but you've implemented your own setter methods, method 2 calls those methods with "nil" as the argument. Whether that's equivalent to method 1 or not depends on how you've implemented those methods. If your custom setters do anything significant when the argument is nil, method 2 would ensure that this code executed.

As Marco said, method 3 is just plain wrong. If you've seen sample code doing that then the author may not actually know what they're doing.

Tom Harrington
"If obj1 and obj2 are properties using @synthesize-d accessors, then method 1 and method 2 are equivalent."No, they're not. Method 1 invokes an accessor, with possible side-effects, method 2 does not. You should *not* use method 2.
mmalc