iOS高级编程之数据存储的几种常见方式

简介

在iOS开发中,基于网络数据的本地存储是提高App客户端操作的用户友好度和提高App的运行流畅度。本文对常用的一些存储方式做了整理,具体常见方式有如下几种:

  • NSUserDefaults
  • NSKeyedArchiver
  • Plist操作
  • 沙盒存储
  • CoreData
  • 第三方存储框架

NSUserDefaults

一般对于一些基本的用户设置,因为数据量很小,我们可以使用OC语言中的 NSUserDefaults类来进行处理。使用方法很简单,只需要调用类中的方法即可。
NSUserDefaults支持的数据类型有:NSNumber(NSInteger、float、double),NSString,NSDate,NSArray,NSDictionary,BOOL.

数组的存取:

NSMutableArray *mutableArray = [[NSMutableArray alloc]initWithObjects:@"1", nil];
//NSUserDefaults只能存储不可变对象
NSArray * array = [NSArray arrayWithArray:mutableArray];
    //存入数组并同步
    [[NSUserDefaults standardUserDefaults] setObject:array forKey:@"mutableArr"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    //读取存入的数组 打印,取出数据赋值给可变数组
    NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:[user objectForKey:@"mutableArr"]];
    NSLog(@"%@",arr);

注意:对相同的Key赋值约等于一次覆盖,要保证每一个Key的唯一性。

字符串的存取:

//将NSString 对象存储到 NSUserDefaults 中
NSString *passWord = @"1234567";
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user setObject:passWord forKey:@"userPassWord"];

图片的存取:

//存储
UIImage *image =[UIImage imageNamed:@"somename"];
NSData *imageData = UIImageJPEGRepresentation(image, 100);//把image归档为NSData
[defaults setObject:imageData forKey:@"image"];
[defaults synchronize];
//读取
NSData *imageData = [defaults dataForKey:@"image"];
UIImage *image = [UIImage imageWithData:imageData];

NSUserDefaults提供了若干简便方法可以存储某些常用类型的值,例如:

- setBool:forKey:
- setFloat:forKey:
- setInteger:forKey:
- setDouble:forKey:
- setURL:forKey:

NSKeyedArchiver

采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法。前一个方法告诉系统怎么对对象进行编码,而后一个方法则是告诉系统怎么对对象进行解码。

归档操作:
如果对Possession对象allPossession归档保存,只需要NSCoder子类NSKeyedArchiver的方法archiveRootObject:toFile: 即可。

NSString *path = [self possessionArchivePath];
[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]

解档操作:
同样调用NSCoder子类NSKeyedArchiver的方法unarchiveRootObject:toFile: 即可

allPossessions = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] retain];

Plist属性列表

plist,全名PropertyList,即属性列表文件,它是一种用来存储串行化后的对象的文件。这种文件,在ios开发过程中经常被用到。这种属性列表文件的扩展名为.plist,因此通常被叫做plist文件。文件是xml格式的。Plist文件是以key-value的形式来存储数据。既可以用来存储用户设置,也可以用来存储一些需要经常用到而不经常改动的信息。

创建

可以通过新建一个.plist的文件创建plist属性列表,创建的字段类型有Array, Dictionary,Boolean, Data, String, Date, Number等。
通过代码创建Plist:

NSFileManager *fm = [NSFileManager defaultManager];
    //找到Documents文件所在的路径
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUSErDomainMask, YES);
    //取得第一个Documents文件夹的路径
    NSString *filePath = [path objectAtIndex:0];
    //把TestPlist文件加入
    NSString *plistPath = [filePath stringByAppendingPathComponent:@"test.plist"];
    //开始创建文件
[fm createFileAtPath:plistPath contents:nil attributes:nil];
删除
[fm removeItemAtPath:plistPath error:nil];
写入
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"zhangsan",@"1",@"lisi",@"2", nil];
//把数据写入plist文件
[dic writeToFile:plistPath atomically:YES];
读取
NSDictionary *dic2 = [NSDictionary dictionaryWithContentsOfFile:plistPath];
//打印数据
NSLog(@"key1 is %@",[dic2 valueForKey:@"1"]);

沙盒存储

沙盒是系统为了ios程序分配的可以读写数据的文件区域。沙盒中有三个重要的文件夹:

1. Documents:用于存储NSUesrDefults之外的数据。

获取方式:

// 获得应用程序沙盒的Documents文件夹路径
NSArray *arrDocumentPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentPath=[arrDocumentPaths objectAtIndex:0];
NSLog(@"Documents path: %@",documentPath);

2. Tmp用于存储临时数据,当数据不再需要的时候我们将删除数据。

 // 获得应用程序沙盒的tmp文件夹路径
 NSString *TmpPath= NSTemporaryDirectory();

3. Library:NSUserDefults的数据保存在LIbrary/Preferences下面。

// 获得应用程序沙盒的Caches文件夹路径
NSArray *arrCachesPaths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory,NSUserDomainMask,YES);
NSString *CachesPath=[arrCachesPaths objectAtIndex:0];
NSLog(@"Caches path: %@",CachesPath);

// 获得应用程序沙盒的Downloads文件夹路径
NSArray *arrDownloadPaths = NSSearchPathForDirectoriesInDomains (NSDownloadsDirectory,NSUserDomainMask,YES);
NSString *loadPathsPath=[arrDownloadPaths objectAtIndex:0];
NSLog(@"Downloads path: %@",loadPathsPath);

CoreData

CoreData是iOS SDK里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据。使用CoreData框架,程序员可以很轻松有效地通过面向对象的接口管理数据。
CoreData框架提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite3数据库文件中,也能够将保存在数据库中的数据还原成OC对象。

增加

- (void)insertData {
    NSEntityDescription*entity = [NSEntityDescriptionentityForName: @"Person"inManagedObjectContext: self.manageObjectContext];

    Person*person = [[Personalloc]initWithEntity: entityinsertIntoManagedObjectContext:self.manageObjectContext];

    person.name=@"钢铁侠";
    person.age=@40;
    person.height=@180;
    __autoreleasing NSError *error;
    [self.manageObjectContextsave:&error];

    if(error) {
        NSLog(@"数据添加失败");
    }else{
        NSLog(@"数据添加成功");
    }
}

更新数据

- (void)updateData{
    //修改数据
    self.selectedPerson.name=@"Mark47";
    self.selectedPerson.age=@1;
    __autoreleasingNSError*error;
    //保存数据
    [self.manageObjectContextsave:&error];
    if(error) {
        NSLog(@"数据更新失败");
    }else{
        NSLog(@"数据更新成功");
    }
}

删除数据

- (void) deleteData{
    [self.manageObjectContextdeleteObject:self.selectedPerson];
    __autoreleasingNSError*error;
    [self.manageObjectContextsave:&error];
    if(error) {
        NSLog(@"数据删除失败");
    }else{
        NSLog(@"数据删除成功");
    }
}

第三方存储框架

FMDB

FMDB是第三方的SQLite数据库,以Objective-C的方式封装了SQLite的C语言API,使用起来更加的方便,对多线程的并发进行处理,所以是线程安全的,轻量级框架,使用灵活。

使用FMDataBase类建立数据库

//1.获得数据库文件的路径
NSString *doc =[NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,NSUserDomainMask, YES)  lastObject];                  
NSString *fileName = [doc stringByAppendingPathComponent: @“student.sqlite”];

//2.获得数据库
FMDatabase *db = [FMDatabase databaseWithPath:fileName];

 //3.使用如下语句,如果打开失败,可能是权限不足或者资源不足。通常打开完操作操作后,需要调用 close 方法来关闭数据库。在和数据库交互 之前,数据库必须是打开的。如果资源或权限不足无法打开或创建数据库,都会导致打开失败。
 if ([db open]){
    //4.创表
    BOOL result = [db executeUpdate:@“CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREM ENT, name text NOT NULL, age integer NOT NULL);”];
       if (result){
          NSLog(@“创建表成功”);
        }
  }

向数据库中增加数据:executeUpdate:

if ([db open]) {  
       NSString *insertSql1= [NSString stringWithFormat:@"INSERT INTO '%@' ('%@', '%@', '%@') VALUES ('%@', '%@', '%@')",TABLENAME, NAME, AGE, ADDRESS, @"张三", @"13", @"济南"];  
       BOOL res = [db executeUpdate:insertSql1];  
       NSString *insertSql2 = [NSString stringWithFormat:@"INSERT INTO '%@' ('%@', '%@', '%@') VALUES ('%@', '%@', '%@')",TABLENAME, NAME, AGE, ADDRESS, @"李四", @"12", @"济南"];  
       BOOL res2 = [db executeUpdate:insertSql2];    
       if (!res) {  
           NSLog(@"error when insert db table");  
       } else {  
           NSLog(@"success to insert db table");  
       }  
       [db close];
   }  

数据库删除数据操作:executeUpdate:

if ([db open]) {  

        NSString *deleteSql = [NSString stringWithFormat:  
                               @"delete from %@ where %@ = '%@'",  
                               TABLENAME, NAME, @"张三"];  
        BOOL res = [db executeUpdate:deleteSql];  

        if (!res) {  
            NSLog(@"error when delete db table");  
        } else {  
            NSLog(@"success to delete db table");  
        }  
        [db close];  

    }

数据库修改数据操作:executeUpdate:

if ([db open]) {  
        NSString *updateSql = [NSString stringWithFormat:@"UPDATE '%@' SET '%@' = '%@' WHERE '%@' = '%@'", TABLENAME,   AGE,  @"15" ,AGE,  @"13"];  
        BOOL res = [db executeUpdate:updateSql];  
        if (!res) {  
            NSLog(@"error when update db table");  
        } else {  
            NSLog(@"success to update db table");  
        }  
        [db close];  

    } 

数据库查询数据操作:executeQuery:

if ([db open]) {  
        NSString * sql = [NSString stringWithFormat:  
                          @"SELECT * FROM %@",TABLENAME];  
        FMResultSet * rs = [db executeQuery:sql];  
        while ([rs next]) {  
            int Id = [rs intForColumn:ID];  
            NSString * name = [rs stringForColumn:NAME];  
            NSString * age = [rs stringForColumn:AGE];  
            NSString * address = [rs stringForColumn:ADDRESS];  
            NSLog(@"id = %d, name = %@, age = %@  address = %@", Id, name, age, address);  
        }  
        [db close];  
    }  

FMDB中的多线程操作:

//1.创建队列
 FMDatabaseQueue *queue = [FMDatabaseQueue   
 databaseQueueWithPath:aPath];
  __block BOOL whoopsSomethingWrongHappened = true;

 //2.把任务包装到事务里
 [queue inTransaction:^(FMDatabase *db, BOOL *rollback) 
   {  
 whoopsSomethingWrongHappened &=  [db     executeUpdate:@“INSERT INTO myTable VALUES (?)”,     [NSNumber numberWith:1]];
whoopsSomethingWrongHappened &= [db
executeUpdata:@“INSERT INTO myTable VALUES (?)”, 
[NSNumber numberWithInt:2]];

whoopsSomethingWrongHappened &= [db  
executeUpdata:@“INSERT INTO myTable VALUES (?)”[NSNumber  
numberWithInt:3]];
//如果有错误 返回
if (!whoopsSomethingWrongHappened)
  { 
    *rollback = YES;
      return;
  }
}];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值