我正在开发一个项目,其中有各种自定义对象。这些自定义对象(其中一些与嵌套可变数组一起使用)需要保存到一个或多个文件中。这样做的最佳方法是什么?我应该创建一个加载和保存文件管理器还是让每个对象处理它是一个更好的主意?
NSCoding
协议:
NSString * const kMyArray = @"myString";
NSString * const kMyBool = @"myBool";
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:_myArray forKey:kMyArray];
[coder encodeBool:_myBool forKey:kMyBool];
//...
}
- (id)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (self) {
_myArray = [coder decodeObjectForKey:kMyArray];
_myBool = [coder decodeBoolForKey:kMyBool];
//...
}
return self;
}
NSKeyedArchiver
保存和加载数据:
//saving collection of Class<NSCoding> objects
NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"data.plist"];
BOOL success = [NSKeyedArchiver archiveRootObject:_collection toFile:path];
//loading
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
if (data) _collection = [NSKeyedUnarchiver unarchiveObjectWithData:data];
如果你想对对象进行编码和解码,你可以看看 NSCoding。这是一种直接的方法。
查看文档:https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/Reference/Reference.html (编辑正确的链接)
我在更新 iOS 版本时遇到了存储对象损坏的问题。这是围绕从 iOS 4.1 到 iOS 4.2 的过渡。
我停止使用 NSCoder 并转而创建自定义文件格式,该格式具有底层 JSON 文件。现在,我可以更好地控制文件版本控制,并且可以轻松进行修复,因为这都是关于解释您自己的数据文件的。
您可以在应用程序包中手动创建一个plist文件(假设Config.plist是plist的名称),并将其复制到Document目录后,您可以通过编程方式对其进行修改。
所以看看这里如何将文件复制到文档目录中: 首先定义两个宏:
#define DOCUMENT_DIR [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
#define PLIST_SETTINGS [DOCUMENT_DIR stringByAppendingPathComponent:@"Config.plist"]
之后-
NSString *configPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
[self copyIfNeededFrom:configPath To:PLIST_SETTINGS];
NSMutableArray* mArrObjects = [NSMutableArray alloc] initWithObjects:obj1,obj2,obj3, nil];
[mArrObjects writeToFile:PLIST_SETTINGS atomically:YES];
[mArrObjects release];
现在给出 copyIfNeededFrom: to:
的定义- (BOOL)copyIfNeededFrom:(NSString *)sourcePath To:(NSString *)destinationPath
{
NSError *error = noErr;
if(![[NSFileManager defaultManager] fileExistsAtPath:destinationPath])
{
[[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:destinationPath error:&error];
}
if(noErr)
return YES;
else
return NO;
}