Cocoa Touch 序列化对象。解码后尝试读取自定义类的数据成员会导致程序崩溃

发布于 2024-11-16 08:52:09 字数 1825 浏览 0 评论 0原文

在尝试对我创建的对象进行编码和解码时,我遇到了一个似乎相当奇怪的错误。我相信我使该对象及其包含的所有对象都符合 NSCoding 和 NSCopying 。我正在尝试编码一个充满“Goals”的 NSMutableArray,它有一个 NSString 标题和一个“ActionSteps”的 NSMutableArray,也符合协议。我可以很好地对对象进行编码,当我解码对象时,它们响应不处理数据成员的函数调用,但是当我尝试读取“目标”的标题时,程序崩溃了,我得到了这个错误消息:

-[__NSArrayM isEqualToString:]:无法识别的选择器发送到实例 接下来是堆栈跟踪,最后是: 程序收到信号:“SIGABRT”。

当我尝试访问目标内“ActionSteps”的标题时,我收到相同的错误消息。

这是我的“目标”类的代码,用于遵守协议。

#pragma mark NSCoding
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:goalName forKey:GoalNameKey];
[encoder encodeObject:actionSteps forKey:ActionStepsKey];
}

这次我尝试打印出解码器返回的任何内容,因为它应该是 NSString,但我遇到了同样的崩溃。

- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
    goalName = [[decoder decodeObjectForKey:GoalNameKey] retain];
    NSLog((NSString *)[decoder decodeObjectForKey:GoalNameKey]);
    actionSteps = [[decoder decodeObjectForKey:ActionStepsKey] retain];
}
return self;
}

#pragma mark -
#pragma mark NSCopying
- (id)copyWithZone:(NSZone *)zone {
Goal *copy = [[[self class] allocWithZone: zone] init];
copy.goalName = [[self.goalName copyWithZone:zone] autorelease];
copy.actionSteps = [[self.actionSteps copyWithZone:zone] autorelease];
return copy;
}

这是用于编码包含我所有“目标”的主 NSMutableArray 的代码:

[NSKeyedArchiver archiveRootObject:goalViewController.goals toFile:[self dataFilePath]];

以及解码:

NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
    goalViewController.goals = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
}
else {
    goalViewController.goals = [[NSMutableArray alloc]init];
}

当我尝试在解码后读取“目标”的标题时,会发生错误

label.text = self.goal.goalName;

I'm having what seems to be a rather strange error when attempting to encode and decode an object I created. I believe I made the object and all the objects it contains conform to NSCoding and NSCopying. I'm attempting to encode a NSMutableArray filled with "Goals" which have a NSString title and a NSMutableArray of "ActionSteps" which also conform to the protocols. I can encode the objects just fine and when I decode the objects they respond to function calls that don't deal with the data members, but when I try to read the title of on of the "Goals" the program crashes and I get this error message:

-[__NSArrayM isEqualToString:]: unrecognized selector sent to instance
followed by a stack trace and finally:
Program received signal: “SIGABRT”.

I get the same error message when I attempt to access the titles of the "ActionSteps" inside the goals.

Here is my code for the "goal" class for conforming to the protocols.

#pragma mark NSCoding
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:goalName forKey:GoalNameKey];
[encoder encodeObject:actionSteps forKey:ActionStepsKey];
}

This time I tried printing out whatever the decoder is returning as it should be an NSString and I got the same crash.

- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
    goalName = [[decoder decodeObjectForKey:GoalNameKey] retain];
    NSLog((NSString *)[decoder decodeObjectForKey:GoalNameKey]);
    actionSteps = [[decoder decodeObjectForKey:ActionStepsKey] retain];
}
return self;
}

#pragma mark -
#pragma mark NSCopying
- (id)copyWithZone:(NSZone *)zone {
Goal *copy = [[[self class] allocWithZone: zone] init];
copy.goalName = [[self.goalName copyWithZone:zone] autorelease];
copy.actionSteps = [[self.actionSteps copyWithZone:zone] autorelease];
return copy;
}

Here is the code for encoding the main NSMutableArray that contains all my "Goals":

[NSKeyedArchiver archiveRootObject:goalViewController.goals toFile:[self dataFilePath]];

and for decoding:

NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
    goalViewController.goals = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
}
else {
    goalViewController.goals = [[NSMutableArray alloc]init];
}

the error occurs when I try to read from the title of a "Goal" after It has been decoded

label.text = self.goal.goalName;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅暮の光 2024-11-23 08:52:09

您在两个解码调用中都有 ActionStepsKey

goalName = [[decoder decodeObjectForKey:ActionStepsKey] retain];
actionSteps = [[decoder decodeObjectForKey:ActionStepsKey] retain];

第一个解码调用应该有 GoalNameKey

goalName = [[decoder decodeObjectForKey:GoalNameKey] retain];
actionSteps = [[decoder decodeObjectForKey:ActionStepsKey] retain];

You have ActionStepsKey in both decode calls:

goalName = [[decoder decodeObjectForKey:ActionStepsKey] retain];
actionSteps = [[decoder decodeObjectForKey:ActionStepsKey] retain];

The first one should have GoalNameKey:

goalName = [[decoder decodeObjectForKey:GoalNameKey] retain];
actionSteps = [[decoder decodeObjectForKey:ActionStepsKey] retain];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文