R – When are released objects finally destroyed

deallocmemoryobjective cpool

When you release an object in Objective-C (assuming its release count is 1) its release count is decremented to 0 and the dealloc method called. Is the object destroyed right there and then after the [super dealloc], or is it added to the pool and destroyed when the pool is drained?

I would assume that released objects are destroyed at the end of dealloc (when [super dealloc] is called) I know autorelease variables are added to the pool, just wanted to be sure what happens to normal released objects.

cheers -gary-

Best Answer

First off, Objective-C the programming language does not have any concept of memory management. Memory management is built into Foundation (the common framework of Cocoa for Mac OS X and Cocoa Touch on iPhone OS). Foundation adds a rootclass NSObject that implements alloc, retain, release and autorelease as convenience wrappers on top of class_createInstance() and object_dispose() functions from the Objective-C run-time.

Since Objective-C is memory management agnostic, adding garbage collection and making all memory management methods on NSObject no-ops was quite easy. But there is no garbage collection on iPhone OS and legacy Mac OS X and there we instead use a reference counting scheme in Cocoa.

An object is created when calling the alloc class method on NSObject or NSProxy from Foundation. These default implementations will call class_createInstance() so that you never need to manually.

An object "dies" when dealloc is run on the root class NSObject. This is when the memory for the object on the heap is released by calling object_dispose(), you will never need to call this function yourself as long as you inherit from NSObject or NSProxy from Foundation.

Autoreleased objects are not treated any special as far as the run-time is concerned, an autoreleased object is just as alive as any other object. What happens when you autorelease an object is approximately;

-(id)autorelease; {
  [NSAutoreleasePool addObject:self];  // retain count +1
  [self release];                      // retain count -1
  return self;
}

Calling autorelease will not decrement the retain count, it will just transfer ownership of the object from the caller to the current autorelease pool. Later when the current autorelease pool goes away, it will call release on all of the objects it owns, and any object no longer owned by anything else is released.