【问题标题】:NSCoding: Custom Class unarchived, but with empty/nil class membersNSCoding:自定义类未归档,但类成员为空/无
【发布时间】:2013-08-21 12:21:10
【问题描述】:

我想持久化一个 NSDictionary,里面装满了自定义对象到光盘:

     NSDictionary *menuList = [[NSMutableDictionary alloc]initWithDictionary:xmlParser.items];
     //here the "Menu List"`s Object are filled correctly

     //persisting them to disc:
     NSArray  *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
     NSString *directory = [paths objectAtIndex:0];
     NSString *fileName = [NSString stringWithUTF8String:MENU_LIST_NAME];
     NSString *filePath = [directory stringByAppendingPathComponent:fileName];

     //saving using NSKeyedArchiver
     NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:menuList];
     [archiveData writeToFile:filePath options:NSDataWritingAtomic error:nil];

     //here the NSDictionary has the correct amount of Objects, but the Objects` class members are partially empty or nil
     NSData *data = [NSData dataWithContentsOfFile:filePath];
     NSDictionary *theMenu = (NSDictionary*)[NSKeyedUnarchiver unarchiveObjectWithData:data];

这里是自定义对象的 .m(存储在 NSDictionary 中的对象类型)

- (id)initWithTitle:(NSString*)tTitle level:(NSString*)tLevel state:(NSString*)tState visible:(BOOL)tVisible link:(NSString*)tLink linkType:(NSString*)tLinkType anId:(NSString*)tId {
if ((self = [super init])) {
    self.anId = tId;
    self.title = tTitle;
    self.level = tLevel;
    self.state = tState;
    self.visible = tVisible;
    self.link = tLink;
    self.linkType = tLinkType;
 }
 return self;
 }


 - (void) encodeWithCoder:(NSCoder *)encoder {
 [encoder encodeObject:self.anId forKey:@"anId"];
 [encoder encodeObject:self.level forKey:@"level"];
 [encoder encodeObject:self.state forKey:@"state"];
 [encoder encodeBool:self.visible forKey:@"visible"];
 [encoder encodeObject:self.title forKey:@"title"];
 [encoder encodeObject:self.link forKey:@"link"];
 [encoder encodeObject:self.linkType forKey:@"linkType"];
 }

 - (id)initWithCoder:(NSCoder *)decoder {

 if(self == [super init]){
    self.anId = [decoder decodeObjectForKey:@"anId"];
    self.level = [decoder decodeObjectForKey:@"level"];
    self.state = [decoder decodeObjectForKey:@"state"];
    self.visible = [decoder decodeBoolForKey:@"visible"];
    self.title = [decoder decodeObjectForKey:@"title"];
    self.link = [decoder decodeObjectForKey:@"link"];
    self.linkType = [decoder decodeObjectForKey:@"linkType"];

}

return self;
 }
 @end

我不知道为什么对象未正确解档,但对象的成员在某处丢失。我认为 NSCoding 方法中的某个地方一定有错误,但我找不到它,非常感谢任何帮助。

【问题讨论】:

  • 错字还是真的if(self == [super init]){
  • 它来自关于该问题的另一个示例,如果您忽略它就可以了,我刚刚删除了它,但问题仍然存在。
  • 我认为它已解决,我将路径中的 NSLibraryDirectory 更改为 NSDocumentDirectory,现在它可以工作了。仍然喜欢接受可以解释我原因的答案。
  • 我确实付出了一些努力来查找 NSDocumentDirectory 和 NSLibraryDirectory 之间的差异,但找不到任何东西。话虽如此,您的代码在错误检查方面非常缺乏 - 例如。您应该将 NSError 传递给 NSData writeToFile 调用。
  • 它似乎不再起作用了。现在无法解释为什么。问题还是一样。

标签: ios objective-c nscoding


【解决方案1】:

实现initWithCoder:方法时,需要正确调用super:

if (self = [super initWithCoder:decoder]) {

正在取消归档的实例具有更多属性,而不仅仅是特定类中的添加。您也不想检查与self 的相等性,您想分配给self

【讨论】:

  • 不,只有当超类实现 协议时才会出现这种情况,在我的例子中,NSObject 没有。我也认为这可能是解决方案并尝试了它,但它导致了 NSInvalidArgumentException。尽管如此,您对自我检查是正确的,这是完全错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
  • 2018-10-06
  • 2013-05-21
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多