Inner which holds a CGPoint
#import <Foundation/Foundation.h>@interface Inner : NSObject {CGPoint point;}
@property CGPoint point;
@end
and Outer which holds an Inner
#import <Foundation/Foundation.h>#import "Inner.h"@interface Outer : NSObject {Inner *inner;}@property (nonatomic, retain) Inner *inner;
@end
That's it! Now figure it out. I do not want to inform the client class about Outer's structure.
First, without any clue as to how this will work, I implement NSCoding for Outer like so (after making the changes to the .h):
- (void)encodeWithCoder:(NSCoder *)aCoder {[aCoder encodeObject:self.inner forKey:@"inner"];}- (id)initWithCoder:(NSCoder *)aDecoder {self.inner = [aDecoder decodeObjectForKey:@"inner"];return self;}
and for Inner
- (void)encodeWithCoder:(NSCoder *)aCoder[aCoder encodeObject:NSStringFromCGPoint(self.point) forKey:@"point"];}- (id)initWithCoder:(NSCoder *)aDecoder {self.point = CGPointFromString([aDecoder decodeObjectForKey:@"point"]);return self;}
Now let's just serialize and them, or something.
Outer *outer = [[[Outer alloc] init] autorelease];outer.inner = [[[Inner alloc] init] autorelease];outer.inner.point = CGPointMake(525, 525);BOOL result = [NSKeyedArchiver archiveRootObject:outer toFile:@"somewhereInAppSandbox"];NSLog(@"how did that go %@", result ? @"yes" : @"no" );
And deserialize them?
Outer *outer = [NSKeyedUnarchiver unarchiveObjectWithFile:@"somewhereInAppSandbox"];NSLog(@"moment of truth %@", NSStringFromCGPoint(outer.inner.point));
Wow, this is actually pretty cool. I mean, not as cool as C#'s automatic XML serialization, but I'll take it.
Now... what happens if we house the Outer in an NSArray?
Outer *outer;NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:@"somewhereInAppSandbox.anArray"];if (array != nil) {outer = [array objectAtIndex:0];NSLog(@"moment of truth %@", NSStringFromCGPoint(outer.inner.point));}outer = [[[Outer alloc] init] autorelease];outer.inner = [[[Inner alloc] init] autorelease];outer.inner.point = CGPointMake(525, 525);array = [[[NSArray alloc] initWithObjects:outer, nil] autorelease];
BOOL result = [NSKeyedArchiver archiveRootObject:array toFile:@"somewhereInAppSandbox.anArray"];NSLog(@"how did that go %@", result ? @"yes" : @"no" );
Awesome. Now I can have a drink. So what was the point? This way we get an object graph, and each object -- via conforming to the NSCoding protocol -- gets to define how it wants to serialize. And standard property-set objects know how to do their own stuff anyway. Nice!
No comments:
Post a Comment