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.