awakeFromNib called multiples times - objective-c

I have an NSViewController associated to a NIB, which itself contained some NSView and NSButton. I was using awakeFromNib to initialize some model classes. It worked just fine, until I added a view-based NSTableView. Now, awakeFromNib is called multiples times. Why is it the case ? and what reliable method could I use to initialize my model classes ? Thanks in advance.

If your NIB file contains a view which is then to be used and instanciated multiple times for your view-based NSTableView then each of these view's instances will receive an awakeFromNib call/message.
Similar question.

Related

NSTableView delegate inside Nib

I have a NSWindowController as part of the work flow with NSDocument. The NSWindowController has an associated xib with a couple of NSTableViews. The datasource for these tableviews is a model defined by the NSDocument. I seem to be missing some information on setting up the outlets. If I setup all the outlets within IB, the datasource(s) are created at the time the nib is instantiated with their default init methods, which don't know about the model. By the time awakeFromNib is called, the datasource has already been queried by the tableview (numberOfRowsInTableView). My work-around is to not hook up the outlets for datasource. I get the model information in setDocument and set the delegates in windowDidLoad. This seems to work. How do I pass around a data model when setting the tableview datasource with IB? Since the outlets are not created when init is called (within the tableview datasource), how would I call out to get the model?
Thanks in advance.
There's an explicit note in the NSTabelView documentation:
Important: It’s possible that your data source methods for populating
the table view may be called before awakeFromNib is called if the data
source is specified in Interface Builder. You should defend against
this by having the data source’s numberOfRowsInTableView: method
return 0 for the number of rows when the data source has not yet been
configured. In awakeFromNib, when the data source is initialized you
should always call reloadData on the table view.

Loading nib using loadNibNamed:owner:options: designate initializer

I have a nib file with its class (UIView) assigned to it in the inspector, So when I need to show that view I loaded it using the method :
loadNibNamed:owner:options:
So if I have to do some initialization when I load the nib, what is the way to know that in the nib's UIView class like the initWithNibName:bundle For the UIViewController?
I appreciate any help :)
You want to use a combination of initWithCoder: and awakeFromNib which are each called at different times during the instantiation (the former) and configuration (the latter).

Using one nib file for multiple NSViewControllers

I have one NSTableView nib that contains a number of cells that will be reused throughout 3 different NSViewControllers. The NSTableView and cells function in the same way and look similar but present different data in each of the different views.
Right now I can set the File's Owner to one of the NSViewController classes, but not all of them meaning I'd have to duplicate the nib 3 times. Given that I'm loading with initWithNibName:bundle I don't see any way to set the File's Owner first either.
How can I use one nib with multiple File's Owner for NSViewControllers?
Any ideas?
Have you tried simply NSViewController or a subclass of it that is an abstract superclass of your view controllers?
One subclass could even be sufficient if the differences between your instances can be managed with conditional logic in the subclass.
Either way, it sounds like you have some refactoring to do, but minimal.
I am an iOS developer not OSX but we also face this problem. In our case I would have used a UIView class(surely you will have NSView kind of class) and then added table on that class and made File's Owner of the table to that view class.
I can reuse this class whenever I want in any view controller by adding this view on that controller and changing its data set.

Subclass UITableViewController, where do I set it up within the UIViewController?

I have a UIViewController, with a UITableView which takes up half the screen.
I also have a subclassed UITableViewController, but I can't figure out how I would associate the subclassed UITableViewController with my table?
It is not clear from your question exactly why you are trying to create a UITableViewController and a UIViewController in this case. Do you have 2 different tables you are trying to control? Or are you trying to do something special to have 2 different controllers managing different parts of a view/subview hierarchy?
Typically, the table for a UITableViewController is created automatically or within a NIB file. From the UITableViewController documentation:
If a nib file is specified via the initWithNibName:bundle: method
(which is declared by the superclass UIViewController),
UITableViewController loads the table view archived in the nib file.
Otherwise, it creates an unconfigured UITableView object with the
correct dimensions and autoresize mask. You can access this view
through the tableView property.
So you would usually not need to associate your subclassed UITableViewController with its table because that is taken care of for you.

What awakeFromNib really is?

I'm just a newbie of Objective C iPhone programming... I see a lot of codes that contains method named "awakeFromNib".. What does it really mean? how and when and where to call this method?
Thanks...
awakeFromNib is called for objects (views, controllers, etc.) that are being archived in xib/nib files. This basically means that xib/nib was unarchived, all connections (IBActions/IBOutlets) for all objects are made and you have a working object graph.
I use it when I have a custom view class that I gave to a certain view in my xib.
You don't call it. After nib file load, every view inside of it, be it button, UIView or something else, calls awakeFromNib from their respective class automatically. You override this method for setup and layout, as you would do with init method if you were creating a subview programmatically.