我正在尝试使用NSKeyedArchiver在iOS应用程序上保存一些持久数据以写入文件,我想稍后使用NSKeyedUnarchiver检索此数据。我创建了一个非常基本的应用程序来测试一些代码,但没有成功。 以下是我正在使用的方法:
- (void)viewDidLoad
{
[super viewDidLoad];
Note *myNote = [self loadNote];
myNote.author = @"MY NAME";
[self saveNote:myNote]; // Trying to save this note containing author's name
myNote = [self loadNote]; // Trying to retrieve the note saved to the file
NSLog(@"%@", myNote.author); // Always logs (null) after loading data
}
-(NSString *)filePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent: @"myFile"];
return filePath;
}
-(void)saveNote:(Note*)note
{
bool success = [NSKeyedArchiver archiveRootObject:note toFile:[self filePath]];
NSLog(@"%i", success); // This line logs 1 (success)
}
-(Note *)loadNote
{
return [NSKeyedUnarchiver unarchiveObjectWithFile:[self filePath]];
}
我用来测试此代码的类如下:
Note.h
#import <Foundation/Foundation.h>
@interface Note : NSObject <NSCoding>
@property NSString *title;
@property NSString *author;
@property bool published;
@end
Note.m
#import "Note.h"
@implementation Note
-(id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init])
{
self.title = [aDecoder decodeObjectForKey:@"title"];
self.author = [aDecoder decodeObjectForKey:@"author"];
self.published = [aDecoder decodeBoolForKey:@"published"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.title forKey:@"title"];
[aCoder encodeObject:self.author forKey:@"author"];
[aCoder encodeBool:self.published forKey:@"published"];
}
@end
我已经看过使用NSUserDefaults(https://blog.soff.es/archiving-objective-c-objects-with-nscoding)的类似示例,但我想将此数据保存到文件中,因为据我所知NSUserDefaults主要用于存储用户首选项,而不是一般数据。我错过了什么吗?提前谢谢。
答案 0 :(得分:0)
考虑一下您的应用首次运行时会发生什么,并且您调用loadNote:
方法并且尚未保存任何内容。
该行:
Note *myNote = [self loadNote];
将导致myNote
为nil
,因为没有加载任何内容。现在想想如何在代码的其余部分中进行级联。
您需要处理没有保存数据的初始情况。
Note *myNote = [self loadNote];
if (!myNote) {
myNote = [[Note alloc] init];
// Setup the initial note as needed
myNote.title = ...
}