Graphics Programs Reference
In-Depth Information
The
unarchiveObjectWithFile:
method will create an instance of
NSKeyedUn-
archiver
and load the archive located at the
itemArchivePath
into that instance.
The
NSKeyedUnarchiver
will then inspect the type of the root object in the archive
and create an instance of that type. In this case, the type will be an
NSMutableArray
because you created this archive with a root object of this type. (If the root object was a
BNRItem
instead,
unarchiveObjectWithFile:
would return an instance of
BNRItem
.)
The newly allocated
NSMutableArray
is then sent
initWithCoder:
and, as you
may have guessed, the
NSKeyedUnarchiver
is passed as the argument. The array
starts decoding its contents (instances of
BNRItem
) from the
NSKeyedUnarchiver
and sends each of these objects the message
initWithCoder:
passing the same
NSKeyedUnarchiver
.
The clever part about
NSKeyedUnarchiver
is that it knows which object is currently
decoding its instance variables. Thus, you don't need to uniquely identify each object in
an archive. You only need to identify the relationship between an object and its instance
variables, and this relationship is already identified by the key used to encode and decode
the object in the
NSCoding
protocol methods.
You can now build and run the application. Any
BNRItem
s a user enters will be available
until the user explicitly deletes them. One thing to note about testing your saving and
loading code: If you kill
Homepwner
from
Xcode
, the
BNRItem
s will not be saved. You
must hit the home button first and then kill it from
Xcode
by clicking the
Stop
button.
Now that you can save and load
BNRItem
s, there is no reason to auto-populate each one
with random data. In
BNRItemStore.m
, modify the implementation of
createItem
so that it creates an empty
BNRItem
instead of one with random data.
- (BNRItem *)createItem
{
BNRItem *p = [BNRItem randomItem];
BNRItem *p = [[BNRItem alloc] init];
[allItems addObject:p];
return p;
}