Reputation: 29519
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?
Upvotes: 2
Views: 140
Reputation: 118761
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!
Upvotes: 2