0

我在 decodeObjectForKey: 调用上得到一个 EXC_BAD_ACCESS。如果有人能在这里发现一个明显的错误,我将不胜感激:

- (NSData *)serialize:(id <NSCoding>)object {
  NSMutableData *data = [[NSMutableData alloc] init];
  NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
  [archiver setOutputFormat:NSPropertyListBinaryFormat_v1_0];
  [archiver encodeObject:object forKey:@"myobject"];
  [archiver finishEncoding];
  return data;
}

- (id)deserialize:(NSData *)data {
  NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
  unarchiver.delegate = self;
  id object = [unarchiver decodeObjectForKey:@"myobject"];
  [unarchiver finishDecoding];
  return object;
}

NSCoding 协议是这样实现的:

- (id)initWithCoder:(NSCoder *)aDecoder {
  self = [super init];
  if (self != nil) {
    _fields = [aDecoder decodeObjectForKey:@"fields"];
    _entries = [aDecoder decodeObjectForKey:@"entries"];
  }
  return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
  [aCoder encodeObject:_fields forKey:@"fields"];
  [aCoder encodeObject:_entries forKey:@"entries"];
}

我不能使用 +unarchiveObjectWithData: 因为我需要设置一个委托来更新反序列化对象:

- (id)unarchiver:(NSKeyedUnarchiver *)unarchiver didDecodeObject:(id)object {
  if([[object class] isSubclassOfClass:[LCEntity class]]) {
    [object setStore:_store];
  }
  return nil;
}

我正在使用 ARC - 所以不用担心内存管理问题。

4

2 回答 2

0

你真的可以那样使用存档器/取消存档器吗?通常,您有一个已编码的根对象,它对图形的其余部分进行编码。尝试使用以下内容:

- (NSData *)serialize:(id <NSCoding>)object {
    return [NSKeyedArchiver archivedDataWithRootObject:object];
}

- (id)deserialize:(NSData *)data {
    return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

当然,此时 -serialize: 和 -deserialize: 方法是相当多余的。他们的调用者应该直接调用 NSKeyedArchiver/NSKeyedUnarchiver。


或者,您的编码对象或其子对象之一可能对-initWithCoder:. 这在堆栈跟踪中应该很明显。

于 2012-08-10T22:20:04.590 回答
0

我可以通过始终在我的 NSKeyedUnarchiverDelegate 中返回对象来解决问题:

- (id)unarchiver:(NSKeyedUnarchiver *)unarchiver didDecodeObject:(id)object {
  if([[object class] isSubclassOfClass:[LCEntity class]]) {
    [object setStore:_store];
  }
  return object;
}

有点奇怪,因为Apple的文档声明如果您不想替换该对象,则应该返回 nil ...

于 2012-08-11T00:33:42.287 回答