5

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.

Myron Slaw
  • 886
  • 9
  • 21
LondonGuy
  • 10,778
  • 11
  • 79
  • 151
  • 2
    Can you be more clear about what's stopping you from using `initWithNibName:bundle:`? – jscs Oct 08 '13 at 20:36
  • Just updated my post to explain why. Since I'm using XCode 5 I gathered that this wouldn't work anymore seeing as NIBs are no longer used. Also I remember seeing the method crossed out when I alt clicked on it's name which means it was deprecated. I may be wrong though. – LondonGuy Oct 08 '13 at 20:47
  • 1
    You can still use `initWithNibName:bundle:`. There's nothing wrong with using `nibs`. Some projects work better with storyboards, some work better with `nibs`. – JRG-Developer Oct 09 '13 at 02:08

2 Answers2

5

NSCoding https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/Protocols/NSCoding_Protocol/Reference/Reference.html

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)

  1. The nib file and referenced resources are loaded into memory
  2. 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.
  3. All outlets and action connections are established (Your IBOUtlets and IBActions) using setValue:forKey: and setTarget:action: respectively.
  4. 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.

Myron Slaw
  • 886
  • 9
  • 21
  • Had to try not to write thirty pages on this. Let me know if I left something important out. – Myron Slaw Oct 09 '13 at 01:42
  • I'm going to have a read. I still don't fully understand what is going on in my code apart for the fact that initWithCoder is a designated initializer that is responsible unarchiving of archived data. Does that even make sense? This is the longest I've been stuck on my journey through ios app development. – LondonGuy Oct 12 '13 at 20:49
  • Check this question out http://stackoverflow.com/questions/2944823/iphone-is-initwithcoder-an-exception-to-the-usual-designated-initializer-desi initWithCoder: is actually an exception to the normal designated initializer rules. – Myron Slaw Oct 13 '13 at 03:23
-1

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?

raveeshg
  • 39
  • 5