UPDATE Addressing your snippet:
CreateGroupViewController * cgvc;
cgvc = [[CreateGroupViewController alloc] init];
// We now _own_ cgvc; we are responsible for its memory
cgvc.delegate = self; // cgvc will send us some fun messages
cgvc.delegate = nil; // Not necessary, because:
[cgvc release]; // cgvc no longer exists
The only case where this makes sense is if the object which is the delegate, call it A
, is being deallocated before the object it was delegating for, call it B
. This might happen if B
is a text field, for example. The text field will stick around after A
disappears, and we don't want B
trying to send messages to deallocated A
:
MyDelegateClass * del = [[MyDelegateClass alloc] init];
myLongLivedObjThatNeedsADelegate.delegate = del;
// Do stuff...
// Release delegate object without setting outlet to nil
[del release];
// ----
// Some time later, in myLongLivedObjectThatNeedsADelegate:
[delegate objShouldDoX:self]; // CRASH! delegate points to
// deallocated instance
If you have an object in a variable, and you no longer need the object, but the variable might (accidentally) get used later, it is a safety measure to set the variable to nil
after releasing the object.
Demonstration:
NSString * str1 = [[NSString alloc] init];
NSString * str2 = [[NSString alloc] init];
NSString * str3 = [[NSString alloc] init];
str1 = nil; // We just leaked the object that was at str1;
// there is no way to release it.
[str1 release]; // Does nothing
[str1 length]; // Also does nothing
[str2 release]; // Release the object
[str2 length]; // CRASH! message sent to deallocated instance
[str3 release];
str3 = nil; // A safety measure
[str3 length]; // Does nothing
When you have properties and synthesized setters, it gets a little bit more interesting. If you have a property:
@property (retain) NSString * myString;
for which you synthesize the setter, the setter will look something like this:
- (void) setMyString:(NSString *)newString {
[newString retain]; // Take ownership of new object
[myString release]; // Relinquish old object
myString = newString; // Rename new object
}
So, if you do self.myString = nil;
, what happens is equivalent to the following:
[self setMyString:nil];
// Inside setMyString: newString is nil
[nil release]; // Does nothing
[myString release]; // Relinquish old object
myString = nil; // Set myString to nil
You see that the synthesized property carries out the conventional "safety" practice automatically for you. This is why you may see people recommend setting properties to nil
.
The last thing to note here is that it doesn't really matter whether you set an ivar to nil
in dealloc
, because that name isn't going to be used anymore. The object that owns it is being destroyed, so the "safety measure" does not apply. Therefore, in dealloc
, you can simply release your ivars without worry.