我有一个保存方法,可以保存从ViewController输入的信息。我将带有保存信息的对象放入一个数组中,我想将该数组存档到一个文件中。该应用程序正常工作,直到unarchive并尝试NSLog信息。该应用程序然后崩溃。任何人都可以帮我找出原因吗?
- (IBAction)Save:(UIButton *)sender {
self.homeworkAssignment = [[Homework alloc] init];
self.homeworkAssignment.className = self.ClassNameField.text;
self.homeworkAssignment.assignmentTitle = self.AssignmentTitleField.text;
self.homeworkAssignment.assignmentDiscription = self.DiscriptionTextView.text;
self.homeworkAssignment.pickerDate = self.DatePicker.date;
NSMutableArray *MyHomeworkArray = [[NSMutableArray alloc] init];
[MyHomeworkArray addObject:self.homeworkAssignment];
//Create file
NSString *filePath = [self dataFilePath];
//Archive my object
[NSKeyedArchiver archiveRootObject:MyHomeworkArray toFile:filePath];
//Unarchive my object to check
Homework *archivedHomework = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"%@ %@", archivedHomework.className, archivedHomework.assignmentTitle);
//^^^^^If I comment this line out, the app does not crash^^^^^^^^^
这是创建文件的方法
- (NSString*)dataFilePath
{
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDir stringByAppendingPathComponent:@"MyHomework.data"];
NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:filePath];
if (!file) {
NSLog(@"Attempting to create the file");
if (![[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]) {
NSLog(@"Failed to create file");
}
else
file = [NSFileHandle fileHandleForWritingAtPath:filePath];
}
return filePath;
}
以下是输出错误信息:
2013-10-09 20:22:03.524 HW1ARC [902:11303] - [__ NSArrayM assignmentTitle]:无法识别的选择器发送到实例0x71c72a0 2013-10-09 20:22:03.524 HW1ARC [902:11303] *由于未捕获异常'NSInvalidArgumentException'而终止应用程序,原因:' - [__ NSArrayM assignmentTitle]:无法识别的选择器发送到实例0x71c72a0' * 第一次抛出调用堆栈: (0x1c96012 0x10d3e7e 0x1d214bd 0x1c85bbc 0x1c8594e 0x28df 0x10e7705 0x1b2c0 0x1b258 0xdc021 0xdc57f 0xdb6e8 0x2df1d3 0x1c5eafe 0x1c5ea3d 0x1c3c7c2 0x1c3bf44 0x1c3be1b 0x1bf07e3 0x1bf0668 0x17ffc 0x1dbd 0x1ce5 0x1) libc ++ abi.dylib:terminate调用抛出异常 (lldb)
编辑:
Homework.h
@interface Homework : NSObject
<
NSCoding
>
@property (nonatomic, strong) NSString *className;
@property (nonatomic, strong) NSString *assignmentTitle;
@property (nonatomic, strong) NSString *assignmentDiscription;
@property (nonatomic, strong) NSDate *pickerDate;
@property (nonatomic, strong) UISwitch *Switch;
@end
Homework.m
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.className forKey:@"className"];
[aCoder encodeObject:self.assignmentTitle forKey:@"assignmentTitle"];
[aCoder encodeObject:self.assignmentDiscription forKey:@"assignmentDiscription"];
[aCoder encodeObject:self.pickerDate forKey:@"pickerDate"];
[aCoder encodeObject:self.Switch forKey:@"Switch"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
self.className = [aDecoder decodeObjectForKey:@"className"];
self.assignmentDiscription = [aDecoder decodeObjectForKey:@"assignmentDiscription"];
self.assignmentTitle = [aDecoder decodeObjectForKey:@"assignmentTitle"];
self.pickerDate = [aDecoder decodeObjectForKey:@"pickerDate"];
self.Switch = [aDecoder decodeObjectForKey:@"Switch"];
}
return self;
}
@end
答案 0 :(得分:0)
显示Homework类的标题,以及它的initWithCoder和encodeWithCoder的实现。
(为了使你想要做的工作,Homework类必须符合NSCoding,这意味着它必须实现这两种方法。)
你的方法dataFilePath没有意义。它为文档目录中的文件创建了一个路径,这很好。它还创建一个NSFileHandle作为局部变量,然后不对该文件句柄做任何事情。没有理由创建文件句柄。它对你没有任何好处,可能会阻止你的文件写入。只需构建一个路径字符串,然后在数组上使用archiveRootObject:toFile:就像你一样。
您报告的错误,无法识别的选择器assignmentTitle发送到NSArray对象听起来就像您有一个僵尸(一个正在被释放的对象,然后在它的内存被用于另一个对象后发送给它的消息。)
您的项目是ARC吗?僵尸在ARC中很不寻常,尽管仍然不是不可能的。
答案 1 :(得分:0)
看看你在做什么。您创建一个Homework
对象,将其添加到一个数组,然后归档该数组。
但是当您取消归档数据时,您将未归档的对象(这是一个数组)分配给Homework
变量。然后尝试像Homework
对象一样使用数组。这就是错误来自__NSArrayM
(可变数组的内部表示)的原因。
此代码:
//Unarchive my object to check
Homework *archivedHomework = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"%@ %@", archivedHomework.className, archivedHomework.assignmentTitle);
应该是:
//Unarchive my object to check
NSMutableArray *homeworkArray = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
Homework *archivedHomework = homeworkArray[0];
NSLog(@"%@ %@", archivedHomework.className, archivedHomework.assignmentTitle);