tags:

views:

35

answers:

1

In my Objective-C class I alloc and release an object multiple times. I also have to release it in dealloc. But if it has been already released previously I might get crash. Is it legal to set object to nil after releasing it? In what cases this would be wrong and cause even more problems?

+2  A: 

Yes yes yes. You almost always should set it to nil after releasing, for exactly the reason you mentioned. You only don't need to if you'll never access it again (like in dealloc) or if you set it to something else immediately afterward.

This is extra-useful because Obj-C has the feature of "nil messaging": if you send a message to nil, it doesn't crash, it just doesn't do anything. So:

MyClass *obj = [[MyClass alloc] init];
[obj doSomething]; // this works
[obj release]; // obj is now invalid
[obj doSomething]; // and this would crash

// but...
MyClass *obj = [[MyClass alloc] init];
[obj doSomething]; // this works
[obj release]; // obj is now invalid
obj = nil; // clear out the pointer
[obj doSomething]; // this is a no-op, doesn't crash

Another example based on your comment:

// we have an object
MyObject *obj = [[MyObject alloc] init];

// some other object retains a reference:
MyObject *ref1 = [obj retain];

// so does another:
MyObject *ref2 = [obj retain];

// we don't need the original reference anymore:
[obj release];
obj = nil;

[ref1 doSomething]; // this works
// now we're done with it
[ref1 release];
ref1 = nil;

// but someone else might still want it:
[ref2 doSomething]; // this works too!
[ref2 release];
ref2 = nil; // all cleaned up!

Read the Memory Management guidelines!

jtbandes
But what if I'm not the only owner of the object and have doubts that it's completely released? The rule I guess should be that I am the only owner and make sure that after release the ref counter is 0. Right?
Michael
I rarely assign nil to objects after releasing them. I usually want my app to crash if I'm passing a message to a nil object. This seems to be masking a deeper problem with the code that could become ugly later.
Greg Sexton
Nope! You can have multiple references to an object. The point is that each owner should take care of its **own** retain/release. I'll edit my answer to demonstrate.
jtbandes
@Greg: I suppose that's one debugging technique, but there are really many more cases when nil messaging is extremely useful.
jtbandes
@Micheal See here for rules on ownership. http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html In particular the section “Memory Management Rules”.
Greg Sexton
This last example was extremely helpful, thanks a lot!
Michael
@Michael are you clear about objects and pointers to them? Setting a variable - that currently points to an object - to nil, has no effect on the object. Mostly you will want to use accessor methods, if you have many retains, releases and =nil in other places you are probably not using accessor methods correctly.
mustISignUp