Friday, August 7, 2009

The 8th property list object

We've been long told that there're only 7 types of property list objects: CFString, CFNumber, CFBoolean, CFDate, CFData, CFArray, and CFDictionary. These are the only types that can be encoded into a property list without conversion. At least it's what on the surface. There's in fact an eighth type of property list object, called _CFKeyedArchiverUID, to support the NSKeyed[Un]Archiver.

An archived data is actually a binary property list. The encoded objects are laid out linearly, and each object has a UID numbered serially. Objects can be linked to each other, forming an "Object Graph". The links are encoded as _CFKeyedArchiverUIDs.

A _CFKeyedArchiverUID is essentially a 32-bit integer. Why isn't a CFNumber be used? Because it would then be impossible to distinguish between a regular number and a link.

Becuase _CFKeyedArchiverUID is not publicly documented (you can find its trace in the CF source code), it is a perfect type to conceal these supposed-to-be internal information.

But it introduce problems when handling with plist files that have a _CFKeyedArchiverUID. Firstly, Apple's Property List Editor does not recognize them. And even worse, these UIDs are stripped when saved. You can try this: open any .nib file, without any modification save it as another file. You'll find that the new file becomes smaller.

Also, _CFKeyedArchiverUID does not have a specialized -description method. When you NSLog a dictionary containing with object, a <NSCFType: 0xpointer> will be displayed (although CFShow does show the content).

In XML format, _CFKeyedArchiverUID will be output as
<dict> <key>CF$UID</key> <integer>123</integer> </dict>

This means any dictionaries containing a single entry with key CF$UID and an integer value will be converted to a _CFKeyedArchiverUID.

No comments:

Post a Comment