美文网首页
iOS中常用数据持久化总结

iOS中常用数据持久化总结

作者: 雷3雷 | 来源:发表于2018-09-13 18:29 被阅读2次

    iOS中常用数据持久化总结

     

    哈哈大p孩 关注

    2016.08.09 17:27* 字数 1155 阅读 1715评论 1喜欢 13

    在项目中我们常需要根据需求存储一些信息,而数据持久化就显得非常必要了,在这里我对数据持久化做个总结。

    在说数据持久化之前,先提一个概念,沙盒。相信大家对他并不陌生,iOS程序默认情况下只能访问程序自己的目录,这个目录被称为沙盒。

    沙盒路径下有好几个文件夹,每个文件夹都有自己的特性。详细代码如下:

    //存放应用程序的源文件,appNSString*pathOne = [[NSBundlemainBundle] bundlePath];NSLog(@"%@", pathOne);//最常用的目录Documents,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。NSString*pathTwo =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;NSLog(@"%@", pathTwo);//caches:iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。Preferences:NSUserDefaults中存储,iTunes同步该应用时会同步此文件夹中的内容,通常保存应用的设置信息。NSString*pathThree =NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES).firstObject;NSLog(@"%@", pathThree);//iTunes不会同步此文件夹,系统可能在应用运行时就删除该目录下的文件,所以此目录适合应用中的一些临时文件,用完就删除NSString*pathFour =NSTemporaryDirectory();NSLog(@"%@",pathFour);

    1.plist文件

    plist文件是将某些特定的类,通过xml的方式保存在目录中。

    可以被序列化的类型只有如下几种:NSArray NSMutableArray NSDictionary NSMutableDictionary NSData NSMutableData NSString NSMutableString NSNumber NSDate

    详细代码如下:

    //1.获取文件路径NSString*path =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;NSString*fileName = [path stringByAppendingPathComponent:@"fei.plist"];//2.存储NSArray*array = @[@"1",@"2",@"3",@"4"];    [array writeToFile:fileName atomically:YES];//atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写YES。//3.读取NSArray*result  = [NSArrayarrayWithContentsOfFile:fileName];NSLog(@"%@", result);

    2.NSUserDefaults

    先上代码,大家先看一下:

    //1.获得NSUserDefaults文件NSUserDefaults*userDefaults = [NSUserDefaultsstandardUserDefaults];//2.向文件中写入内容[userDefaults setObject:@"狮子"forKey:@"猫科动物"];    [userDefaults setBool:YESforKey:@"公的母的"];    [userDefaults setInteger:5forKey:@"多大"];//3.立即同步[userDefaults synchronize];//4.读取文件NSString*name = [userDefaults objectForKey:@"猫科动物"];BOOLsex = [userDefaults boolForKey:@"公的母的"];NSIntegerage = [userDefaults integerForKey:@"多大"];NSLog(@"%@, %d, %ld", name, sex, age);

    一般在这里保存应用程序的配置信息的(我们代驾项目中是把个人信息存储在这里),一般不要在这里保存其他数据。

    如果这里你没有调用synchronize方法的话,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。

    3.NSKeyedArchiver

    归档在iOS中是另一种形式的序列化,只要遵循了NSCoding协议的对象都可以通过它实现序列化。由于决大多数支持存储数据的Foundation和Cocoa Touch类都遵循了NSCoding协议,因此,对于大多数类来说,归档相对而言还是比较容易实现的。

    1.需要在定义的类中实现NSCoding协议 ,一个用来说明如何将对象编码到归档中,另一个说明如何进行解档来获取一个新对象。

    //实现协议的方法//解档- (instancetype)initWithCoder:(NSCoder*)aDecoder {if([superinit]) {self.name = [aDecoder decodeObjectForKey:@"name"];self.age = [aDecoder decodeIntegerForKey:@"age"];          }returnself;}//归档- (void)encodeWithCoder:(NSCoder*)aCoder {    [aCoder encodeObject:self.name forKey:@"name"];    [aCoder encodeInteger:self.age forKey:@"age"];}

    注意:如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。

    2.接下来是使用,将创建类的对象的数据进行归档。

    NSString*file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject stringByAppendingPathComponent:@"maozhuxi.data"];    Person *person = [[Person alloc] init];    person.name =@"毛主席";    person.age =50;//将对象归档是调用NSKeyedArchiver的工厂方法archiveRootObject[NSKeyedArchiverarchiveRootObject:person toFile:file];

    然后在我们需要的地方解档取出这些数据

    //需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile:即可。NSString*file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject stringByAppendingPathComponent:@"maozhuxi.data"];    Person *person = [NSKeyedUnarchiverunarchiveObjectWithFile:file];if(person) {NSLog(@"name == %@", person.name);NSLog(@"age == %ld", person.age);    }

    4.FMDB

    大数据的存储我们一般用FMDB,比如聊天中的信息一般是用FMDB存储的(融云第三方就是这么存储的。。。),他是在sqlite的基础上进行封装的,因为sqlite使用起来不是很好使,所以iOS的大神们封装了这个FMDB,我也在这里记录一下用法以及心得。

    FMDB的下载地址:https://github.com/ccgus/fmdb

    1.将FMDB第三方导入到工程中,如下图:

    Paste_Image.png

    2.在工程文件中导入FMDB.h

    3.创建数据库,并建表格。如下面代码

    - (void)openDataBase {//1.设置文件名NSString*filename = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject stringByAppendingPathComponent:@"xiaoping.db"];//2.打开数据库文件,如果没有会自动创建一个文件_database = [FMDatabase databaseWithPath:filename];if(![_database open]) {NSLog(@"数据库打开失败");    }else{        [_database executeUpdate:@"create table myTable(name,age,sex)"];    }    [_database close];    }

    在指定路径下创建一个数据库文件,并在其中创建一个表格,分别包含三个属性。

    4.向表格中添加数据,如下代码:

    - (void)addSQL {    [_database open];BOOLb = [_database executeUpdateWithFormat:@"insert into myTable(name,age,sex) values (%@,%d,%@);",@"junjie",23,@"man"];BOOLc = [_database executeUpdateWithFormat:@"insert into myTable(name,age,sex) values (%@,%d,%@);",@"xiaohong",22,@"woman"];    [_database close];    b ?NSLog(@"junjie success"):NSLog(@"junjie fail");    c ?NSLog(@"xiaohong success"):NSLog(@"xiaohong fail");}

    在这里添加了两条数据,分别是junjie和xiaohong,注意一下语法。

    5.查询表格中的数据,如下代码:

    - (void)requireSQL {//取得资料[_database open];    FMResultSet *rs = [_database executeQuery:@"select * from myTable"];while([rs next]) {//遍历一下NSString*name = [rs stringForColumn:@"name"];intage = [rs intForColumn:@"age"];NSString*sex = [rs stringForColumn:@"sex"];NSLog(@"name == %@, age == %d, sex == %@",name, age, sex);    }//这里是找出对应的人的对应信息NSString*junjie_sex = [_database stringForQuery:@"select sex from myTable where name = ?",@"junjie"];NSString*xiaohong_sex = [_database stringForQuery:@"select sex from myTable where name = ?",@"xiaohong"];NSLog(@"junjie_sex == %@", junjie_sex);NSLog(@"xiaohong_sex == %@", xiaohong_sex);    [rs close];    [_database close];}

    6.删除操作,代码如下:

    - (void)delegateSQL {    [_database open];    [_database executeUpdate:@"delete from myTable where name = 'junjie'"];    [_database close];}

    上面,除了查询是executeQuery语句,其余全是executeUpdate语句。对于sql语法不熟悉的童鞋,在这里参考一下我写的,如果还不明白,百度一下sql简单语法你就懂了(大学教的。。)

    以上代码敲出来后,有时候我们想通过图形的方式查看,以前在大学学数据库的时候 (那会还是windows),我们用的是MySQL,然后在dos下(终端)能够将表格以图文形式展现出来,在这里我是用DB Browser工具操作的,如下图:

    Paste_Image.png

    很直观的看见你建的表格数据。

    5.CoreData

    1.新建一个工程,并勾选coredata选项:

    Paste_Image.png

    2.建立好以后可以看到xxx.xcdatamodeld,在这里可以添加实体和实体的属性。需要注意的是:实体名字必须以大写开头

    Paste_Image.png

    3.然后新建一个file,记得是NSManagedObject cubclass

    Paste_Image.png

    4.然后勾选自己的工程

    Paste_Image.png

    5.勾选建立的实体

    Paste_Image.png

    6.next后我们即可获得四个文件

    Paste_Image.png

    7.在viewcontrller中导入

    "Student.h"

    "Student+CoreDataProperties.h"

    然后定义成员变量

    {

        AppDelegate *app;

    }

    并在viewdidload中初始化

    app = [UIApplicationsharedApplication].delegate;

    8.接下来是增删改查

    //增- (void)coreDataAdd {//初始化,name后面跟的是刚建的那个实体Student *stu = [NSEntityDescriptioninsertNewObjectForEntityForName:@"Student"inManagedObjectContext:[app managedObjectContext]];      stu.name = [NSStringstringWithFormat:@"junjie%d",arc4random()%10];    stu.sex =@"man";    stu.age = [NSStringstringWithFormat:@"%d", arc4random() %15];//保存[app.managedObjectContext save:nil];}//删除- (void)coreDataDelegate {//读取这个类,entify:定义管理对象,managedObjectContext:被管理的对象上下文NSEntityDescription*entify = [NSEntityDescriptionentityForName:@"Student"inManagedObjectContext:app.managedObjectContext];//建立请求,NSFetchRequest获取数据的请求NSFetchRequest*request = [[NSFetchRequestalloc] init];    [request setEntity:entify];//设置检索条件NSPredicate*predicate = [NSPredicatepredicateWithFormat:@"name = %@",@"e3"];    [request setPredicate:predicate];//遍历所有学生,获取所有学生的信息,存在数组array里面NSArray*array = [app.managedObjectContext executeFetchRequest:request error:nil];if(array.count) {for(Student *stuinarray) {//删除对象[app.managedObjectContext deleteObject:stu  ];        }//保存结果[app.managedObjectContext save:nil];NSLog(@"delegate success");    }else{NSLog(@"没有检索到数据");    }}//改- (void)coreDataUpdate {//读取类NSEntityDescription*entify = [NSEntityDescriptionentityForName:@"Student"inManagedObjectContext:app.managedObjectContext];//建立请求NSFetchRequest*request = [[NSFetchRequestalloc] init];    [request setEntity:entify];//建立检索条件NSPredicate*predicate = [NSPredicatepredicateWithFormat:@"name != %@",@"xiaohong"];    [request setPredicate:predicate];//遍历所有学生,获取所有学生的信息,存在数据array里面NSArray*array = [app.managedObjectContext executeFetchRequest:request error:nil];if(array.count) {for(Student *stuinarray) {            stu.name =@"xiaohong";        }//保存[app.managedObjectContext save:nil];NSLog(@"修改完成");    }else{NSLog(@"没有检索结果");    }}//查- (void)coreDataSelect {//读取这个类NSEntityDescription*entity = [NSEntityDescriptionentityForName:@"Student"inManagedObjectContext:app.managedObjectContext];//建立请求NSFetchRequest*request = [[NSFetchRequestalloc] init];//建立请求的是哪一类[request setEntity:entity];//遍历所有学生,获取所有学生的信息,存在数据array里面NSArray*array = [app.managedObjectContext executeFetchRequest:request error:nil];for(Student *stuinarray) {NSLog(@"%@", stu.name);    }}

    数据持久化常见的就这几种,可以根据自己的需要选择一到两种使用。我一般用小数据存储用NSUserDefaults,大数据存储用FMDB,其他的相对来说用的少。

    相关文章

      网友评论

          本文标题:iOS中常用数据持久化总结

          本文链接:https://www.haomeiwen.com/subject/abihfftx.html