iOS中几种数据持久化方案

概念

所谓持久化就是将数据保存到硬盘中,使得应用重启或者机器重启后可以继续访问之前保存的数据。

方案
  • plist文件(属性列表)
    将某些特定的类,通过XML文件的方式保存在目录中。
    1. 获得文件路径

       NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
       NSString *fileName = [path stringByAppendingPathComponent:@"myplist.plist"];
    2. 存储

       NSArray *array = @[@"123", @"456", @"789"];
       [array writeToFile:fileName atomically:YES];
    3. 读取

       NSArray *result = [NSArray arrayWithContentsOfFile:fileName];
       NSLog(@"%@", result);
  • preference(偏好设置)
    1. 获得NSUserDefaults文件

       NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    2. 向文件中写入内容

       [userDefaults setObject:@"myString" forKey:@"string"];
       [userDefaults setBool:YES forKey:@"bool"];
       [userDefaults setInteger:21 forKey:@"integer"];
    3. 立即同步

       [userDefaults synchronize];
    4. 读取文件

       NSString *name = [userDefaults objectForKey:@"string"];
       BOOL sex = [userDefaults boolForKey:@"bool"];
       NSInteger age = [userDefaults integerForKey:@"integer"];
  • NSKeyedArchiver(归档)
    1. 属性设置

       @interface Person : NSObject //2.设置属性
       @property (strong, nonatomic) UIImage *avatar;
       @property (copy, nonatomic) NSString *name;
       @property (assign, nonatomic) NSInteger age;
       @end

    2.实现协议方法

    NSCoding协议声明了两个方法,这两个方法都是必须实现的。一个用来说明如何将对象编码到归档中,另一个说明如何进行解档来获取一个新对象。

      //解档
      - (id)initWithCoder:(NSCoder *)aDecoder {
          if ([super init]) {
          self.avatar = [aDecoder decodeObjectForKey:@"avatar"];
          self.name = [aDecoder decodeObjectForKey:@"name"];
          self.age = [aDecoder decodeIntegerForKey:@"age"];
          }
          return self;
      }
      //归档
      - (void)encodeWithCoder:(NSCoder *)aCoder {
          [aCoder encodeObject:self.avatar forKey:@"avatar"];
          [aCoder encodeObject:self.name forKey:@"name"];
          [aCoder encodeInteger:self.age forKey:@"age"];
      }

    如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;

    3.使用

    需要把对象归档是调用NSKeyedArchiver的工厂方法 archiveRootObject: toFile: 方法。

      NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
      Person *person = [[Person alloc] init];
      person.avatar = self.avatarView.image;
      person.name = self.nameField.text;
      person.age = [self.ageField.text integerValue];
      [NSKeyedArchiver archiveRootObject:person toFile:file];

    需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile: 即可。

      NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
      Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
      if (person) {
          self.avatarView.image = person.avatar;
          self.nameField.text = person.name;
          self.ageField.text = [NSString stringWithFormat:@"%ld", person.age];
      }
  • SQLite3
    SQLite3的使用还是比较麻烦,在一般开发过程中,使用的都是第三方开源库 FMDB
    1. 打开数据库

       NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.db"];
       FMDatabase *database = [FMDatabase databaseWithPath:path];
       if (![database open]) {
       NSLog(@"数据库打开失败!");
       }
    2. 更新

       //常用方法有以下3种:
       - (BOOL)executeUpdate:(NSString*)sql, ...
       - (BOOL)executeUpdateWithFormat:(NSString*)format, ...
       - (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments
       //示例
       [database executeUpdate:@"CREATE TABLE IF NOT EXISTS t_person(id integer primary key autoincrement, name text, age integer)"];
       //或者
       [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES(?, ?)", @"Bourne", [NSNumber numberWithInt:42]];
    3. 查询

       查询方法有3种
       - (FMResultSet *)executeQuery:(NSString*)sql, ...
       - (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...
       - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments
       查询示例
       //1.执行查询
       FMResultSet *result = [database executeQuery:@"SELECT * FROM t_person"];
       //2.遍历结果集
       while ([result next]) {
           NSString *name = [result stringForColumn:@"name"];
           int age = [result intForColumn:@"age"];
       }
    4. 线程安全
      • 创建队列

          FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
      • 使用队列

          [queue inDatabase:^(FMDatabase *database) {
              [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_1", [NSNumber numberWithInt:1]];
              [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_2", [NSNumber numberWithInt:2]];
              [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_3", [NSNumber numberWithInt:3]];
              FMResultSet *result = [database executeQuery:@"select * from t_person"];
              while([result next]) {
              }
          }];
  • CoreData

    1. 创建项目的时候选择使用Core Data,项目创建成功后,会在AppDelegate类中自动添加相关代码,此外,还会自动生成一个数据模型文件。如果项目在创建的时候没有选择使用Core Data,但是在后面需要使用,那么需要手动的添加AppDelegate中的相关代码。此外还需要手动添加一个Data Model文件。
      在创建Data Model文件时需要注意文件名要与AppDelegate.m中managedObjectModel方法中提到的文件名称相匹配。

    2. 有了Data Model文件后,就可以在里面添加实体和关系,实际上就是向数据库中添加表格和建立表格之间的关联。
    3. 创建好实体后,可以通过添加NSManagedObject subclass文件,系统可以自动添加实体对应的数据模型类。
    4. 通过代码实现数据库的操作
      • 插入数据

          -(void)insert {       
           AppDelegate *delegate = [[UIApplication sharedApplication] delegate];        
          //1. 获得context    
          NSManagedObjectContext *context = delegate.managedObjectContext;    
          //2. 找到实体结构,并生成一个实体对象   
           /*     NSEntityDescription实体描述,也就是表的结构     参数1:表名字     参数2:实例化的对象由谁来管理,就是context     */   
            NSManagedObject *stu = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:context];  
            NSManagedObject *class1 = [NSEntityDescription insertNewObjectForEntityForName:@"Classes" inManagedObjectContext:context];    
            [class1 setValue:[NSNumber numberWithInt:1] forKey:@"c_id"];    
            [class1 setValue:@"一班" forKey:@"c_name"];        
            //3. 设置实体属性值    
            [stu setValue:[NSNumber numberWithInt:1] forKey:@"s_id"];    
            [stu setValue:@"jerehedu" forKey:@"s_name"];    
            [stu setValue:class1 forKey:@"s_class"];        
            //4. 调用context,保存实体,如果没有成功,返回错误信息    
            NSError *error;    
            if ([context save:&error]){        
              NSLog(@"save ok");    
            } else{        
              NSLog(@"%@",error);   
            }}
      • 查询全部数据

          -(void)selectAll {    
          AppDelegate *delegate = [[UIApplication sharedApplication] delegate]; 
          NSManagedObjectContext *context = delegate.managedObjectContext;        
          NSEntityDescription *stu = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:context];        
          //构造查询对象    
          NSFetchRequest *request = [[NSFetchRequest alloc] init];    
          [request setEntity:stu];        
          //执行查询,返回结果集    
          NSArray *resultAry = [context executeFetchRequest:request error:nil];        
          //遍历结果集    
          for (NSManagedObject *enity in resultAry) {        
              NSLog(@"id=%i name=%@ class=%@",[[enity valueForKey:@"s_id"] intValue],[enity valueForKey:@"s_name"],[[enity valueForKey:@"s_class"] valueForKey:@"c_name"]);    
          }}
      • 查询指定数据

          - (void)selectAll {    
                  AppDelegate *delegate = [[UIApplication sharedApplication] delegate];        
                  NSManagedObjectContext *context = delegate.managedObjectContext;        
                  NSEntityDescription *stu = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:context];        
                  //构造查询对象    
                  NSFetchRequest *request = [[NSFetchRequest alloc] init];    
                  [request setEntity:stu];        
                  //执行查询,返回结果集    
                  NSArray *resultAry = [context executeFetchRequest:request error:nil];        
                  //遍历结果集    
                  for (NSManagedObject *enity in resultAry) {        
                      NSLog(@"id=%i name=%@ class=%@",[[enity valueForKey:@"s_id"] intValue],[enity valueForKey:@"s_name"],[[enity valueForKey:@"s_class"] valueForKey:@"c_name"]);    
                  }}
      • 删除指定数据

          - (void)delete{    
              //删除 先找到,然后删除    
              AppDelegate *delegate = [[UIApplication sharedApplication] delegate];    
              NSManagedObjectContext *context = delegate.managedObjectContext;        
              NSEntityDescription *stu = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:context];        
              NSFetchRequest *request = [NSFetchRequest new];    
              [request setEntity:stu];        
              //构造查询条件,相当于where子句    
              NSPredicate *predicate = [NSPredicate predicateWithFormat:@"s_id=%i",1];        
              //把查询条件放进去    
              [request setPredicate:predicate];    
              //执行查询    
              NSManagedObject *obj = [[context executeFetchRequest:request error:nil] lastObject];    
              //删除    
              if (obj) {        
                  [context deleteObject:obj];        [context save:nil];    
                  }        
                  [self selectAll];
                  }

转载于:https://www.cnblogs.com/AliliWl/p/6108528.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值