3

I have two nibs: Parent.xib and Child.xib.

I've included the Child nib inside the Parent nib to simplify binding. I set the subview programmatically in loadView. The problem is, awakeFromNib is getting called twice in Child's controller.

I think I understand why this is happening. When Parent finishes loading, it sends an awakeFromNib to its objects, and since Child is the file owner of its nib, it calls awakeFromNib on itself as well.

Am I understanding this right? I was originally under the impression that awakeFromNib should only be called once per instance. Am I not supposed to embed nib in nib?

See Sample Project: https://github.com/panupan/AwakeFromNibTest

panupan
  • 1,212
  • 13
  • 15

2 Answers2

5

There are situations where awakeFromNib can be called more than once per instance, such as the one you setup. Another case is a controller that loads more than one nib object. You can work around this if you really want to, but a better design is not to have to. From the NSNibAwaking Protocol Reference:

It is recommended that you maintain a one-to-one correspondence between your File’s Owner objects and their associated nib files. Loading two nib files with the same File’s Owner object causes that object’s awakeFromNib method being called twice, which could cause some data structures to be reinitialized in undesired ways. It is also recommended that you avoid loading other nib files from your awakeFromNib method implementation.

In your particular example, there is no reason to embed one nib file inside another one. You get the memory footprint disadvantage of having to load both of them into memory without the convenience of having all the objects in a single nib file. You should split them up and use NSObjectController instances in the nib files to deal with binding between them.

torrey.lyons
  • 5,519
  • 1
  • 23
  • 30
  • Let's say I want to use NSObjectController in both nibs. Would the best way to link them be to bind them through code? The reason I embedded one nib inside another one is so bindings could be achieved without writing code. Thanks. – panupan Jul 21 '12 at 02:00
  • You make an `IBOutlet` to the `NSObjectController` instance. Then in `awakeFromNib` you use `-setContent:` to bind the object controller to the object you want it to represent in the other nib file. In Interface Builder you can set the class of the object the controller is representing and any keys it has that you will use. Then you can use bindings to the object controller in your nib file as if it was the original object. In IB set the controller key to "selection" and the model key path to whatever the key is on the original object. – torrey.lyons Jul 21 '12 at 08:17
0

Even if I have two different file owners, awakeFromNib is still called twice.

If I have an NSWindowController subclass (MyWindowController) and in its nib I have a ProjectController object which contains awakeFromNib which loads a view from a nib, the view's controller will get an awakeFromNib call, and then the original ProjectController will receive awakeFromNib again.

Trygve
  • 1,317
  • 10
  • 27