Tuesday, February 17, 2009

Nib file, Binding, and Memory Management in Cocoa

"Objects in a nib file are initially created with a retain count of 1. As it rebuilds the object hierarchy, however, Cocoa autoreleases any objects that have a parent or owning object, such as views nested inside view hierarchies. By the time the nib-loading code is complete, only the top-level objects in the nib file have a positive retain count and no owning object. This makes the top-level objects a potential memory leak if your code does not assume responsibility for them. "

You don't need to worry about this if the File's Owner is NSWindowController or NSViewController, or their subclasses.

Use either of the following ways to dealloc the top-levels

- use [NSNib instantiateNibWithOwner: topLevelObjects:] to keep an array to top-level objects, and release them in dealloc

- create an IBOutlet for each top-level object in the nib and release the objects in dealloc, can use property
@property (nonatomic, retain) IBOutlet NSTableView *mTableView;



Note you may still get a memory leak if you use Cocoa bindings in the nib. This occurs when an object in the nib binds to the File’s Owner. The File’s Owner never gets deallocated in this case, and thus neither do the top-level objects.

- Unbind the bindings programmatically. You’ll need to do this elsewhere than the File Owner’s dealloc,
which won’t get called unless you unbind.

- Bind to a different object in the nib rather than to the File’s Owner.


Now in MainMenu.nib, the file's owner is NSApplication.

(1) Subclass NSApplication so that it has outlets to all the top-level
objects and release them on NSApplication dealloc. (rarely used?)
(2) Instantiate a delegate to handle applicationWillTerminate: and use
that to release all objects, except, urm, how about the delegate
itself
(3) Don't worry about it, since the app is going away anyway and will
take with it all top-level objects.