Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

initWithFrame not called, but awakeFromNib is

Tags:

cocoa

I am trying to subclass NSOutlineView. Here is my code:

OutlineViewSublcass.h:

#import <Cocoa/Cocoa.h>  @interface OutlineViewSubclass : NSOutlineView {  }  @end 

OutlineViewSubclass.m:

#import "OutlineViewSubclass.h"  @implementation OutlineViewSubclass  - (id)initWithFrame:(NSRect)frame {     self = [super initWithFrame:frame];     printf("debug A\n");     return self; }  - (void)awakeFromNib {     printf("debug B\n"); }  @end 

The debug output is:

debug B 

Why isn't (id)initWithFrame:(NSRect)frame being called?

like image 638
Sam Lee Avatar asked Jan 11 '09 19:01

Sam Lee


People also ask

What is it called when you are awake from the nib?

The commonly recommended place to do custom initialization for custom views is in the initWithFrame or initWithCoder methods. When you are defining parts of your UI in IB, initWithCoder is the one of these that is called by the nib-loading code.

What is awake from nib Swift?

The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive, but only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.


2 Answers

Official Apple answer for this is Creating a Custom View.

View instances that are created in Interface Builder don't call initWithFrame: when their nib files are loaded, which often causes confusion. Remember that Interface Builder archives an object when it saves a nib file, so the view instance will already have been created and initWithFrame: will already have been called.

The awakeFromNib method provides an opportunity to provide initialization of a view when it is created as a result of a nib file being loaded. When a nib file that contains a view object is loaded, each view instance receives an awakeFromNib message when all the objects have been unarchived. This provides the object an opportunity to initialize any attributes that are not archived with the object in Interface Builder.

like image 34
Doug Richardson Avatar answered Sep 19 '22 15:09

Doug Richardson


Cocoa controls implement the NSCoding protocol for unarchiving from a nib. Instead of initializing the object using initWithFrame: and then setting the attributes, the initWithCoder: method takes responsibility for setting up the control when it's loaded using the serialized attributes configured by Interface Builder. This works pretty much the same way any object is serialized using NSCoding.

It's a little bit different if you stick a custom NSView subclass in a nib that doesn't implement NSCoding, in that case initWithFrame: will be called. In both cases awakeFromNib will be called after the object is loaded, and is usually a pretty good place to perform additional initialization in your subclasses.

like image 65
Marc Charbonneau Avatar answered Sep 19 '22 15:09

Marc Charbonneau