All view objects, when instantiated in Interface Builder, are “freeze-dried” when saving the nib. That is, they’re written to the nib file on disk in a special way we call “serializing”. All this means is that the complex object graph that constitutes the object is converted to a stream of bytes that can be written to disk and then read back in later by a mechanism that understands the stream.
Since this is a pain in the ass, Apple gave us the NSCoding protocol and the NSCoder class. Since our views have been archived previously during the serialization process, they must be unarchived during nib loading. To do this, we use something called a coder which is capable of decoding the object from its freeze-dried state.
NSCoding and NSCoder are documented here:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/Reference/Reference.html
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSCoder_Class/Reference/Reference.html
Look at it this way: you have a button and a bunch of stuff the button knows how to do. You’ve also got all of the state knowledge of the button (frame, bounds, control size, its class, and the other things it knows about itself), and you have connections to and from other objects in the nib. How do you save this data to disk? It’s not magic, it’s just a process of translating it all to a stream of bytes. When you’ve done that, you just need a way to reverse the process. That’s what coders do. Some archive, some unarchive.
When an archived (serialized) view object is read in from a nib, it is given an -initWithCoder: message. Usually what you’ll do is invoke the superclass’s implementation, check it for a valid object on return, and then perform your custom subclass’s custom setup. Then when you’re done, return the object. It’s just like -initWithFrame:, except we’re unarchiving.
Even “Custom View” is sent -initWithCoder:, but your custom class is not sent that message. Why? Well, “Custom View” actually encodes an NSCustomView object into the nib. When the nib is unarchived, the NSCustomView object is initialized with -initWithCoder:, swaps in your custom subclass, and then sends -initWithFrame: to it. You can see this in the call stack of a custom view during -initWithFrame:.
Here is a document that describes the so-called “life cycle” of a nib:
Extremely important information for anyone doing custom control work.