Inherits from: NSCoder : NSObject
Conforms to: NSObject
(NSObject)
Declared in: Foundation/NSArchiver.h
initForWritingWithMutableData:
archiveRootObjectToFile | Archives a graph of objects to a file. |
archivedDataWithRootObject | Archives a graph of objects into an NSMutableData object. |
NSArchiver, a concrete subclass of NSCoder, provides a way to encode Objective-C objects into an architecture-independent format that can be stored in a file. When you archive a set of objects, the class information and instance variables for each object are written to the archive. NSArchiver's companion class, NSUnarchiver, decodes the data in an archive and creates a set of objects equivalent to the original set.
NSArchiver stores the archive data in a mutable-data object (NSMutableData). After encoding the objects, you can have the NSArchiver object write this mutable-data object immediately to a file, or you can retrieve the mutable-data object for some other use.
The easiest way to archive an object is to invoke a single class method-either archiveRootObjectToFile or archivedDataWithRootObject, depending on whether you want the encoded data to be stored in a file immediately. These convenience methods create a temporary NSArchiver and send it an encodeRootObject message-you need do no more. However, if you want to customize the archiving process (for example, by substituting certain classes for others), you must instead create an instance of NSArchiver yourself, configure it as desired, and send it an encodeRootObject message explicitly.
The "root object" that you specify as the argument to any of these three methods indicates the starting point for archiving. The NSArchiver commences archiving by invoking the root object's encodeWithCoder: method. That method typically encodes the root object's instance variables, which isn't necessarily a straightforward process-the instance variables can themselves be other objects that respond to encodeWithCoder:, and so on, yielding a possibly complex graph of objects that need to be archived.
The fact that many objects contain references to other objects poses two problems for archiving. The first is redundancy. An object graph isn't necessarily a simple tree structure. Two objects can contain references to each other, for example, creating a cycle. To address this problem, NSArchiver overrides NSCoder's encodeRootObject method to keep track of all the objects encountered while traversing the graph. The first time an object is encountered, the object is encoded normally. On subsequent occurances of the same object, a reference to the original object is encoded instead of the object itself.
The second problem is that it's not always appropriate to archive the entire graph. To use an example from the Application Kit, when you archive an NSView as the root object, its subviews should be archived, but not its superview. In this case, the superview is considered an extraneous part of the graph. To solve this dilemma, NSArchiver implements conditional archiving, overriding the minimal encodeConditionalObject method that's inherited from NSCoder. A class's encodeWithCoder: method can invoke encodeConditionalObject to archive inessential object instance variables. The NSArchiver doesn't actually archive a conditionally encoded object unless some other object in the graph encodes it unconditionally (using one of the other encode...Object: methods declared by NSCoder). When everything is unarchived, all original references to the conditionally encoded object are properly restored as references to the single unarchived object. For example, an NSView encodes its superview with encodeConditionalObject, because it doesn't own the superview but does need to preserve its connection to it if some other object archives the superview.
In contrast, encodeObject: unconditionally instructs an object to encode itself. This method is most often used in a class's encodeWithCoder: method for instance variables that are intrinsic to the receiver and essential for proper functioning.
All the objects to be placed in a single archive must be interconnected members of a single graph. In other words, there can only be one root object per archive. The only recommended way to archive objects is to send an NSArchiver a single encodeRootObject message, whether directly, or indirectly by invoking archiveRootObjectToFile or archivedDataWithRootObject. Don't try to add data to the archive by invoking any of NSCoder's other encode... methods, except from within the encodeWithCoder: method of each object that's part of the graph. (These encodeWithCoder: methods are invoked automatically when you encode the root object.)
To extract an object graph from an archive, use the NSUnarchiver class method unarchiveObjectWithFile: or unarchiveObjectWithData:, assigning the return value to the desired root object.
It's possible to create an archive that doesn't contain any objects. To archive other data types, invoke one of the encode... methods, such as encodeByte, encodeChar, or encodeDouble, directly for each data item to be archived, instead of using encodeRootObject. When you create an archive in this way, the corresponding unarchiving code must follow exactly the same sequence of data types.
This approach shouldn't be used to archive objects. Use encodeRootObject instead, to avoid the problems mentioned in the previous section and to simplify unarchiving.
An NSSerializer provides another means to store data in an architecture-independent format. See the NSSerializer class specification for more information.
NSArchiver's superclass, NSCoder, supplies methods for both encoding and decoding. However, only the encoding methods are applicable to NSArchiver-don't send an NSArchiver any decode... messages. (Similarly, don't send encode... messages to an NSUnarchiver.)
- Initializing an NSArchiver
- initForWritingWithMutableData:
- Archiving data
- archivedDataWithRootObject
- archiveRootObjectToFile
- encodeRootObject
- encodeConditionalObject
- Getting the archived data
- archiverData
- Substituting classes or objects
- classNameEncodedForTrueClassName
- encodeClassNameIntoClassName
- replaceObject
public static boolean archiveRootObjectToFile(Object rootObject, String path)
true
for the second. Returns true
upon
success.See Also: archivedDataWithRootObject, - writeToFile:atomically: (NSData)
public static NSData archivedDataWithRootObject(Object rootObject)
See Also: initForWritingWithMutableData:, encodeRootObject
- (NSMutableData *)archiverData
public String classNameEncodedForTrueClassName(String trueName)
See Also: encodeClassNameIntoClassName
public void encodeClassNameIntoClassName(String trueName, String inArchiveName)
See Also: classNameEncodedForTrueClassName
public void encodeConditionalObject(Object object)
This method should be invoked only from
within an encodeWithCoder: method. If object is null
,
the NSArchiver encodes it unconditionally as null
.
This method throws an exception if no root object has been encoded.
public void encodeRootObject(Object rootObject)
This message must not be sent more than once to a given NSArchiver; an exception is thrown if a root object has already been encoded. Therefore, don't attempt to reuse an NSArchiver; instead, create a new one. To encode multiple object graphs, use distinct NSArchivers.
- (id)initForWritingWithMutableData:(NSMutableData
*)data
null
.See Also: archiverData
public void replaceObject(Object object, Object newObject)