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

来源:互联网 发布:战地1终极版 淘宝 编辑:程序博客网 时间:2024/06/10 09:25

简介

在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 &= [dbexecuteUpdata:@“INSERT INTO myTable VALUES (?)”, [NSNumber numberWithInt:2]];whoopsSomethingWrongHappened &= [db  executeUpdata:@“INSERT INTO myTable VALUES (?)”[NSNumber  numberWithInt:3]];//如果有错误 返回if (!whoopsSomethingWrongHappened)  {     *rollback = YES;      return;  }}];
0 0