这是一个很好的问题,我自己也一直想知道。所以,我写了一个小测试程序来尝试一下。四个类别:ClassA、ClassB、ClassC和MyBaseClass。ClassA, ClassB, and ClassCinherit from MyBaseClasswhich 符合NSCoding并提供两个属性:name和age。除了这些之外,A、B 和 C 类是相同的,ClassA并且ClassB还包含对 的实例的引用ClassC。ClassA并且ClassB还覆盖initwithCoder:并encodeWithCoder:解码和编码它们对 . 实例的引用ClassC。这是顶级代码的样子:
ClassA *a = [[ClassA alloc] initWithName:@"Mr. A" age:11];
ClassB *b = [[ClassB alloc] initWithName:@"Mrs. B" age:22];
ClassC *c = [[ClassC alloc] initWithName:@"Ms. C" age:33];
b.c = c;
a.c = c;
NSArray *rootObject = @[a, b, c];
NSString *const kFilePath = @"/Users/myname/Documents/testarchive";
BOOL result = [NSKeyedArchiver archiveRootObject:rootObject toFile:kFilePath];
NSLog(@"result = %@", (result) ? @"YES" : @"NO");
NSArray *newRootObject = [NSKeyedUnarchiver unarchiveObjectWithFile:kFilePath];
NSLog(@"new root object = %@", newRootObject);
对象完美地序列化和反序列化。另外,反序列化后,a.c并b.c指向同一个实例ClassC——也就是说,它们的对象指针具有相同的地址。
显然,在NSKeyedArchiver'sencodeObject:forKey:中,会进行测试以查看被编码isEqualTo:的对象是否是先前编码的对象,如果是,则存储引用而不是完整的对象。相反的情况必须发生在NSKeyedUnarchiver'sdecodeObject:forKey:中。很酷!