Will the pointer to an object go to nil
when its count goes to 0 or when dealloc is called? Why or why not?
views:
392answers:
4I'm not sure if the pointer goes to nil or if it just points to invalid data, but its good coding convention to assign your variables to nil after you release them.
No, it won't, because the deallocation does not have the power to change the pointer. It could only do this is you passed a pointer to the pointer.
If you want to ensure it's set to nil, you have to do it yourself.
Some consider this good practice, some consider it a waste of time since your code should be structured to not use pointers after deallocation (until reallocated).
I actually lean towards the latter camp but I can see why people want to protect themselves from accessing freed memory (programming defensively is rarely a bad idea).
Think of this situation:
void *p = malloc (100);
while (someCondition)
{
// do something with p
}
free (p);
// p is not set to NULL for you, it still points to where it always did
Similarly, when an Objective-C object is deallocated, any pointers to that object are still pointing to where it was. This causes errors when another object is allocated into the same space (or even if nothing is allocated into the same space).
Under the normal retain-release memory model, no. With garbage collection enabled, this happens if the pointer is declared as __weak
(for Objective-C objects, the default is __strong
). The garbage collector will zero out weak references for you when they are disposed of, which makes them ideal for pointing to delegates and semi-transient objects. See also NSPointerArray, NSMapTable and NSHashTable and their support for weak relationships as well. (NOTE: One must understand that a weak reference will not prevent an object from being garbage collected; it is zeroed when no strong references point to the same address. See this document for a brief summary of this behavior.)
There are many other benefits to Objective-C garbage collection, and I heartily recommend using it if you can. (It's available on OS X 10.5+, but not on iPhone OS.) The performance improvements in Snow Leopard are most impressive, and it was already wicked fast to begin with.
That being said, @darren has a good point: it's usually good practice to nil your own variables when releasing their contents. If you're looking to avoid dangling pointers to over-released objects, your best bet is to adopt the habit of nilling the variable yourself. It won't incur runtime overhead, and it's readable. More importantly, setting variables to nil helps the garbage collection system work most effectively, since it indicates memory that can be safely reclaimed. The code will also then work in both modes perfectly.
However, I generally don't nil out values in -dealloc
since the memory you're modifying is about to be reclaimed, and if some other part of the code may encounter an error due to using a released value, they ought not be using a deallocated object to begin with. (This often happens when one object hasn't properly retained another, and the latter is deallocated, leaving a dangling pointer.) Possible exceptions to this might include staged tear-down where non-nil references might cause problems within dealloc itself, but this type of behavior generally doesn't (and shouldn't) occur when destroying an object.