我正在开发一个将数据保存到本地文件系统的应用程序。会被保存的数据主要是NSString和NSDate。数据不会经常保存,在典型的使用情况下,新数据可能会输入10次。数据当然也应该是可检索的(CRUD)
我应该如何保存这些数据?首先,有必要对这些对象进行建模吗?如果没有,我应该使用属性列表吗?还是SQLLite3 ?
否则我应该存档类模型吗?使用SQLLite3吗?
编辑:我不小心遗漏了一些关于应用程序的重要信息。实际上,我的应用程序将有2个具有聚合关系的数据模型。我的第一个数据模型(我们叫它DataA)它会有一个NSString NSDate也会有对第二个数据模型的引用(我们叫它DataB)它本身会包含一个NSString和一个NSArray。现在问题变得更复杂了。如果DataB中的一个对象被删除,它当然应该在DataA中停止存在(但DataA的其余部分应该保持不变)
这种类型的数据似乎非常容易存储和检索,并且没有任何其他依赖关系,例如非常复杂的对象图。
您应该将这些数据存储在平面文件或NSUserDefaults
中。
我将给您一个两者的例子,使用NSCoding
协议使用对象归档:
@interface ApplicationData <NSCopying, NSCoding> {}
@property (nonatomic, strong) NSDate *someDate;
@property (nonatomic, strong) NSDate *someOtherDate;
@property (nonatomic, copy) NSString *someString;
@property (nonatomic, copy) NSString *someOtherString;
@end
@implementation ApplicationData
@synthesize someDate = _someDate, someOtherDate = _someOtherDate, someString = _someString, someOtherString = _someOtherString;
- (NSArray *)keys {
static dispatch_once_t once;
static NSArray *keys = nil;
dispatch_once(&once, ^{
keys = [NSArray arrayWithObjects:@"someString", @"someOtherString", @"someDate", @"someOtherDate", nil];
});
return keys;
}
- (id) copyWithZone:(NSZone *) zone {
ApplicationData *data = [[[self class] allocWithZone:zone] init];
if(data) {
data.someString = _someString;
data.someOtherString = _someOtherString;
data.someDate = _someDate;
data.someOtherDate = _someOtherDate;
//...
}
return data;
}
- (void) encodeWithCoder:(NSCoder *) coder {
[super encodeWithCoder:coder];
NSDictionary *pairs = [self dictionaryWithValuesForKeys:[self keys]];
for(NSString *key in keys) {
[coder encodeObject:[pairs objectForKey:key] forKey:key];
}
}
- (id) initWithCoder:(NSCoder *) decoder {
self = [super initWithCoder:decoder];
if(self) {
for(NSString *key in [self keys]) {
[self setValue:[decoder decodeObjectForKey:key] forKey:key];
}
}
return self;
}
@end
然后,在你的应用委托中,你可以这样做:
@interface AppDelegate (Persistence)
@property (nonatomic, strong) ApplicationData *data;
- (void)saveApplicationDataToFlatFile;
- (void)loadApplicationDataFromFlatFile;
- (void)saveApplicationDataToUserDefaults;
- (void)loadApplicationDataFromUserDefaults;
@end
@implementation AppDelegate (Persistence)
@synthesize data;
- (NSString *)_dataFilePath {
static NSString *path = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{
path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) stringByAppendingPathComponent:@"xAppData.dat"];
});
return path;
}
- (void)loadApplicationDataFromUserDefaults {
NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"appData"];
self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}
- (void)saveApplicationDataToUserDefaults {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
[[NSUserDefaults standardUserDefaults] setObject:archivedData forKey:@"appData"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)loadApplicationDataFromFlatFile {
NSData *archivedData = [NSData dataWithContentsOfFile:[self _dataFilePath]];
self.data = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}
- (void)saveApplicationDataToFlatFile {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.data];
[archivedData writeToFile:[self _dataFilePath] atomically:YES];
}
@end
免责声明:我没有测试过这段代码
如果只有有限的数据集,NSUserDefault是不错的选择。但是如果你考虑过滤和抓取,那么你应该看看Core Data来存储对象。
即使对象图是最小的,你将获得缓存的对象管理和自由的撤销/重做管理
我建议你用NSUserDefaults
。这无疑是存储应用相关信息和任何应用相关数据的最佳方法。检查文档!!