NSCoder和/或NSKeyedUnarchiver如何处理同一对象的多个解码?

Eri*_*c L 3 macos objective-c nscoding cocoa-design-patterns nscoder

我想知道如何NSCoder处理下次解码时由多个对象共享和编码的对象.它会制作对象的两个副本,还是会解码并在解码它的所有其他对象之间共享一个对象?

我提供了一个类似下面这种情况的小例子.

例:

  1. 应用程序启动
  2. 对象A和对象B将对象C设置为其委托
  3. 应用程序收到终止通知
  4. 对象A和对象B 编码自身及其所有对象(包括其委托)
  5. 应用程序关闭并重新启动
  6. 对象A和对象B 解码自身及其所有对象(包括其委托)

对象A和对象B在步骤6之后是否共享相同的解码对象,或者它们各自都有自己的副本?

bbu*_*bum 7

他们将共享对同一对象的引用(除非您不遗余力地改变该行为).

即NSCoding可以处理完全循环的,全向的,复杂连接的对象图(只要所有图形参与者都正确支持NSCoding).

请注意,编码委托是非常不典型的.代理人通常无政府主义者之后连接到未归档的对象图,代理人充当归档模型层(或归档视图层,在IB的情况下)之间的一种管道 - 故事对于XIB文件来说更复杂.但是......足够接近)和你的应用程序的其余部分.


小智 5

这是一个很好的问题,我一直都在想这个问题.所以,我写了一个小测试程序来试试.四类:ClassA,ClassB,ClassC,和MyBaseClass.ClassA,ClassBClassC继承MyBaseClass符合NSCoding并提供两个属性:nameage.除了它们之外,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);
Run Code Online (Sandbox Code Playgroud)

对象完美地序列化和反序列化.此外,反序列化,之后a.cb.c指向的同一个实例ClassC-也就是说,他们的对象指针的地址相同.

显然,在NSKeyedArchivers内encodeObject:forKey:,进行测试以查看对象是否被编码isEqualTo:为先前编码的对象,如果是,则存储引用而不是完整对象.反过来必须发生在NSKeyedUnarchiver's decodeObject:forKey:.很酷!