Inherits From: NSObject
Conforms To: NSObject (NSObject)
Declared In: Foundation/NSCoder.h
NSCoder is an abstract class that declares the interface used by subclasses to take objects from dynamic memory and code them into and out of some other format. This capability provides the basis for archiving (where objects and other structures are stored on disk) and distribution (where objects are copied to different address spaces). See the NSArchiver and NSUnarchiver class specifications for more information on archiving.
NSCoder operates on the basic C and Objective C typesint, float, id, and so on (but excluding void * and union)as well as on user-defined structures and pointers to these types.
NSCoder declares methods that a subclass can override if it wants:
. To encode or decode an object only under certain conditions, such as it being an intrinsic part of a larger structure (encodeRootObject: and encodeConditionalObject:).
. To allow decoded objects to be allocated from a specific memory zone (setObjectZone:).
. To allow system versioning (systemVersion).
NSCoder differs from the NSSerializer and NSDeserializer classes in that NSCoders aren't restricted to operating on property list objects (objects of the NSData, NSString, NSArray, and NSDictionary classes). Also, unlike NSSerializers, NSCoders store type information along with the data. Thus, an object decoded from a stream of bytes will be of the same class as the object that was originally encoded into the stream.
Encoding and Decoding Objects
In OpenStep, coding is facilitated by methods declared in several places, most notably the NSCoder class, the NSObject class, and the NSCoding protocol.
The NSCoding protocol declares the two methods (encodeWithCoder: and initWithCoder:) that a class must implement so that objects of that class can be encoded and decoded. When an object receives an encodeWithCoder: message, it should send a message to super to encode inherited instance variables before it encodes the instance variables that it's class declares. For example, a fictitious MapView class that displays a legend and a map at various magnifications, might implement encodeWithCoder: like this:
- (void)encodeWithCoder:(NSCoder *)coder
[coder encodeValuesOfObjCTypes:"si@", &mapName, &magnification, &legendView];
Objects are decoded in two steps. First, an object of the appropriate class is allocated and then it's sent an initWithCoder: messages to allow it to initialize its instance variables. Again, the object should first send a message to super to initialized inherited instance variables, and then it should initialize its own. MapView's implementation of this method looks like this:
- (id)initWithCoder:(NSCoder *)coder
self = [super initWithCoder:coder];
[coder decodeValuesOfObjCTypes:"si@", &mapName, &magnification, &legendView];
Note the assignment of the return value of initWithCoder: to self in the example above. This is done in the subclass because the superclass, in its implementation of initWithCoder:, may decide to return a object other than itself.
There are other methods that allow an object to customize its response to encoding or decoding. NSObject declares these methods:
Method Typical Use
classForCoder: Allows an object, when being encoded, to substitute a class other than its own. For example, the private subclasses of a class cluster substitute the name of their public superclass when being archived.
replacementObjectForCoder: Allows an object, when being encoded, to substitute another object for itself. For example, an object might encode itself into an archive, but encode a proxy for itself if it's being encoded for distribution.
awakeAfterUsingCoder: Allows an object, when being decoded, to substitute another object for itself. For example, an object that represents a font might, upon being decoded, release itself and return an existing object having the same font description as itself. In this way, redundant objects can be eliminated.
See the NSObject class specification for more information.