iOS持久存储策略



我正在开发一个将数据保存到本地文件系统的应用程序。会被保存的数据主要是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。这无疑是存储应用相关信息和任何应用相关数据的最佳方法。检查文档!!

最新更新