iOS持久存储策略

Pet*_*rbo 17 cocoa-touch persistence objective-c save

我正在开发一个将数据保存到本地文件系统的应用程序.将保存的数据主要是NSString和NSDate.通常不会保存数据,在典型使用情况下可能会输入10次新数据.数据当然也应该是可检索的(CRUD)

我该如何保存这些数据?首先是有必要对这些物体进行建模吗?如果不是我应该使用属性列表?还是SQLLite3?

另外我应该归档班级模型吗?使用SQLLite3?

编辑:我不小心遗漏了一些关于该应用程序的重要信息.实际上我的应用程序将拥有2个具有聚合关系的数据模型.所以我的第一个数据模型(让我们称之为DataA)将有一个NSString和NSDate也将引用第二个数据模型(让我们称之为DataB),它本身将由NSString和NSArray组成.所以现在变得有点复杂了.如果DataB中的对象被删除,它当然应该不再存在于DataA中(但DataA的其余部分应保持不变)

Jac*_*kin 18

这种数据似乎非常易于存储和检索,并且没有任何其他依赖性,例如可怕的复杂对象图.

您应该将此数据存储在平面文件中或中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
Run Code Online (Sandbox Code Playgroud)

然后,在您的应用程序委托中说,您可以这样做:

@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
Run Code Online (Sandbox Code Playgroud)

免责声明:我没有测试过这段代码.