Sunday, May 17, 2009

Cocoa: What is "File's Owner" in a nib?

One of the things I had most trouble with while writing my first Cocoa application was understanding what a File's Owner in a nib file was and what role it fulfilled.

Apple's documentation seems to imply that understanding File's Owner is important (it is) but doesn't really do a good job of explaining the concept. And I'm not alone - this email thread contains a pretty good summary of what Apple's documentation says and the confusion it might create. That same thread has several peoples' attempts to explain what it is. I really didn't get too much from those explanations and ended up explaining it to myself by piecing together data from a few experiments. Now that I think I understand what it's for, I figured I should try and put my take out there as well in case it ends up helping someone else in the future.

The File's Owner of your primary nib file is, by default, the NSApplication class and this comes ready-made for you when you create your Cocoa application. If your application has just the one nib file, you really don't need to worry about File's Owner. But if that's true, your application is probably really trivial or not well written.

Generally, each new window/sheet your application creates should be contained in it's own nib for faster loading of your app and smaller runtime footprint. When adding a nib to your application in XCode, you'll noticed that the File's Owner is set to NSObject by default (select the File's Owner object in the nib and launch Tools -> Identity Inspector). I recommend setting this to a derived type for two reasons:
  1. So that you're forced to think about who the File's Owner of the nib is.
  2. So that you don't make a silly error while defining the owner of the nib - everything is an NSObject, after all.
A nib file is loaded dynamically at runtime usually in response to some user action (clicking a button, selecting a menu option, etc). Loading the nib is done, usually, using the NSDocumentController or the NSWindowController classes. Just because these classes help load the nib doesn't mean they must 'own' the nib. The File's Owner of the nib is the object that makes communication possible between this new nib and other parts of the application. Let's explore this further.

The document/window loaded in the nib can have one of the following purposes:
  1. an informative view that isn't interactive (About box, for example)
  2. get some more user input to feed into other parts of the application
#1 is the simple case - by my definition, since there is no communication to be enabled, the File's Owner for this nib is not important. But based on my previous recommendation of not using NSObject as the File's Owner, what class should be set as the File's Owner? The object (NSDocumentController/NSWindowController) which loaded the nib can be made owner of the nib, and the nib loaded using the method overload that doesn't need an owner specified.

#2 is the interesting case - if this is a form that takes in some user input it is required that this information be communicated back to another part of the application. But no one on the outside really has access to controls in this form. No one, except the File's Owner. In this case, the File's Owner should be an instance of a class that you've previously created, and the type of that instance is what you set to be the File's Owner's class in the Identity Inspector. It's important here to understand that the File's Owner isn't a 'new instance' of the class you specified. In fact, the File's Owner is set to an instance provided when the nib was loaded (see the last parameter of initWithWindowsNibName).

So your application likely had an instance of an object created previously, which is what you would pass in as the owner of the file. That instance can now expose IBOutlets linked to fields of the form, which can then be used by other parts of your application that already have a reference to this instance. This is what Apple documentation means when it refers to the File's Owner as a proxy.

Hopefully, this will help someone else who's learning to work with Cocoa and needs to get some clarity around the File's Owner.

9 comments:

jalopezsuarez said...

Thanks for your effort to try to explain the File's Owner architecture...

I found it very useful!

gibberish said...

Hi, great post!

But however, I wonder if there is a difference between setting an instance to be the File's Owner and creating an instance of an class by adding a "blue box" object to the NIB/XIB. And then have all of the IB connections connected to this class instead and use it as an controller class?

Adrian Hosey said...

"Blue box" objects are real objects that are alloc'd and init'd when the XIB is loaded. Orange wireframe objects, including File's Owner, are proxy objects. A XIB can have more than one proxy object. (Although I've never had a need beyond File's Owner, myself.)
For more details on mapping proxies to real objects at runtime, see the documentation for loadNibNamed:owner:options: in NSBundle.

yehnan said...

Excellent explanation. Thanks.

ozgur uksal said...

I see File's Owner icon as a visual tool that helps me to connect my controller object to the view. This connection is established without writing any code. At the end, those objects can talk to each other.

In other programming environments, I would do the same by creating an instance of the controller first in my main file; and then inside the Controller constructor method, I would make a new view by passing an instance of my controller to view's constructor. As a result, they would be able to communicate.

Ozgur Uksal

Eugene T.S. Wong said...

Thanks. I'm not sure that I understand it all, but I think that I understand some of it.

Mitul said...

good...one thanks :)

VĂ­ctor Varillas said...

Than you very much! It was really helpful!

Noel Cody said...

Thank you!