3

In NSCoder, you can call encodeObject: and encodeObject:forkey:. And this for many data types. What is the difference beetween those calls? How to use them? Why isn't there a encodeDataObject:forkey: or encodePropertyList:forKey:?

zoul
  • 102,279
  • 44
  • 260
  • 354
Oliver
  • 23,072
  • 33
  • 138
  • 230
  • just google and you will find hundreds of programs and its uses... :) – Anoop Vaidya Nov 14 '12 at 17:06
  • NSCoder operates on objects, scalars, C arrays, structures, and strings, and on pointers to these types. It does not handle types whose implementation varies across platforms, such as union, void *, function pointers, and long chains of pointers. A coder object stores object type information along with the data, so an object decoded from a stream of bytes is normally of the same class as the object that was originally encoded into the stream. An object can change its class when encoded, however; this is described in Archives and Serializations Programming Guide. – Anoop Vaidya Nov 14 '12 at 17:17

1 Answers1

3

Keyed vs. Unkeyed Accessors

Most of the time you just call the encodeSomething:forKey: method and supply a key that you later use to get the value back from a decoder:

- (void) encodeWithCoder: (NSCoder*) coder
{
    [coder encodeObject:someProperty forKey:@"someProperty"];
}

- (id) initWithCoder: (NSCoder*) decoder
{
    self = [super init];
    if (self) {
        [self setSomeProperty:[decoder decodeObjectForKey:@"someProperty"]];
    }
    return self;
}

The unkeyed version of the call is older, I guess that serialization used to work differently back before 10.2.

Specialized Object Accessors

There isn’t a separate encodeDataObject: call since NSData conforms to NSCoding, so that you can encode it using regular encodeObject:. The same applies to property lists – a property list is just a dictionary, and a dictionary is a regular object that can be encoded using encodeObject:.

What maybe got you confused is the number of specialized methods for encoding primitive types like BOOL or NSUInteger. These have to do with the type system. When encoding and decoding objects, the interface can use the id type and it works regardless of the particular object type:

// can pass NSObject*, NSData*, any object
- (void) encodeObject: (id) anObject {…}
- (id) decodeObject {…}

There is no such general, “wildcard” type for primitive types, therefore the number of specialized getters and setters:

- (void) encodeBool: (BOOL) flag {…}
- (BOOL) decodeBool {…}

Theoretically you could use void* and cast, but that’s clumsy and the encoding interface wouldn’t know the size of the object to encode anyway.

zoul
  • 102,279
  • 44
  • 260
  • 354
  • Thank you, but I still don't understand the reason why the Data and property do not have their mirror method that can be used with a forKey, to retrieve them later... ? – Oliver Nov 14 '12 at 21:32
  • What kind of object are your data and your property lists? – zoul Nov 15 '12 at 07:11
  • Why ? Whatever my data type are, their should be a reason why those methods are built-in like this... – Oliver Nov 15 '12 at 16:53
  • 1
    Well, in Objective-C it’s common to have raw data represented as NSData and property lists as an NSDictionary. And as I already said, both can be encoded and decoded quite conveniently by NSCoder. – zoul Nov 15 '12 at 17:53