I can't use initWithNibName:bundle seeing as I'm now using the latest XCode (5). After some research I found an alternative: initWithCoder.
Example:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self){
// code here
}
return self;
}
What I'm trying to understand is how this is an alternative to initWithNibName?
Currently studying with a big nerd ranch book for ios which was written for ios6 and previous versions of xode and experimenting with the coreLocation framework.
In the code below I've replaced the initWithNibName. I also done this in an earlier tutorial using that same initializer and it worked but I have trouble moving on in tutorial books if I don't fully understand a chapter. The apple docs don't always make sense instantly. Usually a combination of stackoverflow answers and re-reading helps things sink in.
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self){
//create location manager object
locationManager = [[CLLocationManager alloc] init];
//there will be a warning from this line of code
[locationManager setDelegate:self];
//and we want it to be as accurate as possible
//regardless of how much time/power it takes
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//tell our manager to start looking for it location immediately
[locationManager startUpdatingLocation];
}
return self;
}
What is the code above doing? It looks like a designated initializer but the name and the return type of the argument baffle me. Would appreciation some help here.
Kind regards
Update:
From what I've gathered in XCode 5 the use of storyboards is encouraged and I don't see an option to not use storyboards. The tutorials I'm following from this book are using XCode 4.3 where nibs were available.
In order to understand what is going on with this method in regards to a view controller from a nib (or storyboard), you must understand NSCoding.
When objects are unarchived with NSCoding, you get a cascade effect for all objects it it owns. initWithCoder: is sent to one object, it is unfrozen, it is then sent to the objects it owns etc.
This is what the nib loading system uses to unfreeze all the objects you created in interface builder.
Here is a quick rundown of what the nib loading system does (from the docs)
- The nib file and referenced resources are loaded into memory
- The object graph created in the nib is unarchived (NSCoding) This actually depends on the type of object. UIViews are sent initWithFrame, UIViewControllers are sent initWithcoder since they conform to NSCoding and all other objects are just sent init.
- All outlets and action connections are established (Your IBOUtlets and IBActions) using setValue:forKey: and setTarget:action: respectively.
- awakeFromNib is then sent to all objects in the nib
Look here for more details under the object loading process section. https://developer.apple.com/library/ios/documentation/cocoa/conceptual/LoadingResources/CocoaNibs/CocoaNibs.html
The point is initWithCoder will be called from your viewController when using a nib or storyboard because that is how the system unfreezes your object graph, and the properties you set on those objects in interface builder.
Also remember that a storyboard is just a collection of nib files with some metadata describing how they are related.
No worries.. We can still use -[NSViewController initWithNibName:bundle]. Are you sure that you are sub-classing your controller from NSViewController and overriding initWithNibName:bundle?
来源:https://stackoverflow.com/questions/19257725/am-i-right-in-saying-initwithnibnamebundle-is-used-to-manually-load-nib-files-a