Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory management in Objective-C and setting pointers to nil

Will the pointer to an object go to nil when its count goes to 0 or when dealloc is called? Why or why not?

like image 939
SVA Avatar asked Jan 09 '10 03:01

SVA


2 Answers

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).

like image 79
paxdiablo Avatar answered Sep 24 '22 13:09

paxdiablo


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.

like image 26
Quinn Taylor Avatar answered Sep 25 '22 13:09

Quinn Taylor