iOS中常用的四种数据持久化方法

iOS中常用的四种数据持久化方法

OS中的数据持久化方式,基本上有以下四种:属性列表、对象归档、SQLite3和Core Data、

  • NSUserDefaults,用于存储配置信息
  • SQLite,用于存储查询需求较多的数据
  • CoreData,用于规划应用中的对象
  • 使用基本对象类型定制的个性化缓存方案

属性列表

涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults​ standardUserDefaults​]

@interface User : NSObject <NSCoding>  
@property (nonatomic, assign) NSInteger userID;  
@property (nonatomic, copy) NSString *name;  
@end 

使用方法
1).分开存取

// 存  
[[NSUserDefaults standardUserDefaults] setInteger:userID forKey:@”userID”];  
​[[NSUserDefaults standardUserDefaults] setObject:name forKey:@”name”];  
// 取  
NSInteger uId = [[[NSUserDefaults standardUserDefaults] integerValueForKey:@”userID”];  
NSString* name = [[NSUserDefaults standardUserDefaults] stringForKey:@”name”];​ 

2).按对象存取

// 存  
[[NSUserDefaults standardUserDefaults] setObject:self forKey:@”user”];  
// 取  
User* u = [[NSUserDefaults standardUserDefaults] objectForKey”@”user”];

对象归档

要使用对象归档,对象必须实现NSCoding协议.大部分Object C对象都符合NSCoding协议,也可以在自定义对象中实现NSCoding协议,要实现NSCoding协议,实现两个方法:
- (void) encodeWithCoder:(NSCoder )encoder 与 -(void)initWithCoder:(NSCoder )encoder
同时,建议对象也同时实现NSCopying协议,该协议允许复制对象,要实现NSCopying协议须实现 -(id)copyWithZone:(NSZone *)zone 方法 。

@interface User : NSObject <NSCoding>  
@property (nonatomic, assign) NSInteger userID;  
@property (nonatomic, copy) NSString *name;  
​@end  

@implementation User  
// 以下两个方法一定要实现,不然在调用的时候会crash  
- (void)encodeWithCoder:(NSCoder *)aCoder;   
{  
// 这里放置需要持久化的属性  
[aCoder encodeObject:[NSNumber numberWithInteger:self.userID] forKey:@”userID”];  
[aCoder encodeObject:self.name forKey:@"name"];  
}  
- (id)initWithCoder:(NSCoder *)aDecoder  
{  
if (self = [self init])  
{  
//  这里务必和encodeWithCoder方法里面的内容一致,不然会读不到数据  
self.userID = [[aDecoder decodeObjectForKey:@"userID"] integerValue];  
self.name = [aDecoder decodeObjectForKey:@"name"];  
}  
return self;  
}  

// 使用方法  
+ (BOOL)save {  
NSError *error = nil;  
// 确定存储路径,一般是Document目录下的文件  
NSString* fileName = [self getFileName];  
NSString* filePath = [self getFilePath];  
if (![[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error]) {  
NSLog(@”创建用户文件目录失败”);  
return NO;  
}  
return [NSKeyedArchiver archiveRootObject:self toFile:[fileName:userId]];  
}  
​@end  

SQLite3​

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。
SQLite嵌入到使用它的应用程序中,它们共用相同的进程空间,而不是单独的一个进程。从外部看,它并不像一个RDBMS,但在进程内部,它却是完整的,自包含的数据库引擎。 嵌入式数据库的一大好处就是在你的程序内部不需要网络配置,也不需要管理。因为客户端和服务器在同一进程空间运行。SQLite 的数据库权限只依赖于文件系统,没有用户帐户的概念。SQLite 有数据库级锁定,没有网络服务器。它需要的内存,其它开销很小,适合用于嵌入式设备。你需要做的仅仅是把它正确的编译到你的程序。
SQLite的使用:

将数据加入数据库
    if (sqlite3_open(self.filename.UTF8String, &database) == SQLITE_OK) {

        //2、执行插入语句
        NSString * sql = [NSString stringWithFormat: @"insert into t_student (name,age) values ('%@',%zd);",@"haha",arc4random_uniform(100)];

        char * errmsg;

        sqlite3_exec(database, sql.UTF8String, NULL, NULL, &errmsg);

        if (errmsg) {
            NSLog(@"插入失败");
        } else {
            NSLog(@"插入成功");
        }

        //3、关闭数据库
        sqlite3_close(database);
    }
删除数据
    if (sqlite3_open(self.filename.UTF8String, &database) == SQLITE_OK) {

        //2、执行插入语句
        NSString * sql = @"delete from t_student where name = 'haha'";

        char * errmsg;

        sqlite3_exec(database, sql.UTF8String, NULL, NULL, &errmsg);

        if (errmsg) {
            NSLog(@"删除失败");
        } else {
            NSLog(@"删除成功");
        }

        //3、关闭数据库
        sqlite3_close(database);
    }
更改数据
    if (sqlite3_open(self.filename.UTF8String, &database) == SQLITE_OK) {

        //2、执行插入语句
        NSString * sql = @"update t_student set name = 'gaga' where age > 50";

        char * errmsg;

        sqlite3_exec(database, sql.UTF8String, NULL, NULL, &errmsg);

        if (errmsg) {
            NSLog(@"更新失败");
        } else {
            NSLog(@"更新成功");
        }

        //3、关闭数据库
        sqlite3_close(database);
    }
查找数据

    if (sqlite3_open(self.filename.UTF8String, &database) == SQLITE_OK) {

        //2、执行查询语句

        //1、准备查询操作

        NSString * sql = @"select * from t_student;";
        // arg3 : 传-1

        //查询的句柄,游标
        sqlite3_stmt * stmt;

        if (sqlite3_prepare(database, sql.UTF8String, -1, &stmt, NULL) == SQLITE_OK) {
            //查询数据
            while (sqlite3_step(stmt) == SQLITE_ROW) {

                //获取表数据的内容
                //sqlite3_column_text('句柄',字段索引值)

                NSString * name = [NSString stringWithCString:(const char *)sqlite3_column_text(stmt, 1) encoding:NSUTF8StringEncoding];

                NSLog(@"name = %@",name);

                NSUInteger  age = sqlite3_column_int(stmt, 2);

                NSLog(@"age = %zd",age);
            }
        }
        //3、关闭数据库
        sqlite3_close(database);
    }

SQLite第三方库FMDB使用:

创建数据库
    NSString * filename = [NSString cachaPathName:@"data.sqlite"];
    NSLog(@"%@",filename);

    //1、创建数据库
    self.database = [[FMDatabase alloc] initWithPath:filename];
    //2、打开数据库
    if ([self.database open]) {
        NSLog(@"打开数据库成功");

        //3、创建表
        BOOL flag = [self.database executeUpdate:@"create table if not exists t_student (id integer primary key autoincrement ,name text, age integer);"];

        if (flag) {
            NSLog(@"创建表成功");
        } else {
            NSLog(@"创建表失败");
        }
        //4、关闭数据库
        [self.database close];

    } else {
        NSLog(@"打开数据库失败");
    }
添加数据
    if ([self.database open]) {

        BOOL flag = [self.database executeUpdate:@"insert into t_student (name,age) values (?,?)",@"dahuan",@18];

        if (flag) {
            NSLog(@"插入成功");
        }else {
            NSLog(@"插入失败");
        }

        [self.database close];
    }
删除数据
    if ([self.database open]) {

        BOOL flag = [self.database executeUpdate:@"delete from t_student"];

        if (flag) {
            NSLog(@"删除成功");
        }else {
            NSLog(@"删除失败");
        }

        [self.database close];
    }
更改数据
    if ([self.database open]) {

        BOOL flag = [self.database executeUpdate:@"update t_student set name = 'xiaohong' where name = 'dahuan'"];

        if (flag) {
            NSLog(@"修改成功");
        }else {
            NSLog(@"修改失败");
        }

        [self.database close];
    }
查找数据
    if ([self.database open]) {

        //返回查询数据的结果集
        FMResultSet * rs = [self.database executeQuery:@"select * from t_student"];

        //查询表中的每一个记录
        while ([rs next]) {
            NSString * name = [rs stringForColumn:@"name"];
            NSUInteger age = [rs intForColumn:@"age"];

            NSLog(@"name = %@, age = %@",name,@(age));

        }

        [self.database close];
    }

CoreData

CoreData本质上是使用SQLite保存数据,但是它不需要编写任何SQL语句。
要使用CoreData,需要在Xcode中的数据模型编辑器中设计好各个实体以及定义好他们的属性和关系。之后,通过操作这些对象,结合CoreData完成数据的持久化:

将数据加入数据库

  Person * p  = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.objectContext];

    //添加数据
    p.name = @"pengp";
    p.age = @18;

    Book * b = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:self.objectContext];

    b.name = @"九阴真经";
    b.price = @2.5;

    p.book = b;

    NSError * error;

    //保存数据
    if ([self.objectContext save:&error]) {
        NSLog(@"插入成功");
    } else {
        NSLog(@"插入失败%@",error);
    }

删除数据

    NSFetchRequest * request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];

    request.predicate = [NSPredicate predicateWithFormat:@"name CONTAINS %@",@"xiao"];

    NSArray * datalist = [self.objectContext executeFetchRequest:request error:nil];

    for (Person * p in datalist) {

        //删除person
        [self.objectContext deleteObject:p];
        [self.objectContext deleteObject:p.book];
    }

    if ([self.objectContext save:nil]) {
        NSLog(@"删除成功");
    } else {
        NSLog(@"删除失败");
    }

更改数据库

 NSFetchRequest * request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];

    request.predicate = [NSPredicate predicateWithFormat:@"name CONTAINS %@",@"da"];

    NSArray * datalist = [self.objectContext executeFetchRequest:request error:nil];

    for (Person * p in datalist) {

        p.name = @"xiaohuan";
        p.age = @2;
        p.book.price = @0.8;
    }

    if ([self.objectContext save:nil]) {
        NSLog(@"修改成功");
    } else {
        NSLog(@"修改失败");
    }

查询数据库

    //创建查询请求
    NSFetchRequest * request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];

//    request.predicate = [NSPredicate predicateWithFormat:@"name CONTAINS %@",@"da"];

//    request.predicate = [NSPredicate predicateWithFormat:@"%K > %@",@"age",@22];

//    request.predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS %@",@"book.name",@"九阳"];

//    //一次查询多少条
//    [request setFetchLimit:1];
//    //从哪里开始查询
//    [request setFetchOffset:1];

    //获取查询到的数据
    NSError * error;

    NSArray * datalist = [self.objectContext executeFetchRequest:request error:&error];

    if (!error) {

        //懒加载,使用哪个表,就查那个表
        for (Person * p  in datalist) {
            NSLog(@"name = %@, age = %@ book = %@ price = %@",p.name,p.age,p.book.name,p.book.price);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS的MMKV是一个高性能、轻量级的键值存储库,可以用于持久化数据。它由微信团队开发,通过使用C++编写的底层存储引擎,提供了比NSUserDefaults更快速和可靠的存储解决方案。 要在iOS使用MMKV进行持久化,你可以按照以下步骤进行操作: 1. 集成MMKV库:首先,需要将MMKV库添加到你的iOS项目。你可以通过CocoaPods或手动导入方式添加依赖。具体的集成步骤可以参考MMKV的官方文档。 2. 创建MMKV实例:在使用MMKV之前,你需要创建一个MMKV实例来操作数据。可以使用下面的代码创建一个MMKV实例: ``` // 导入MMKV头文件 #import <MMKV/MMKV.h> // 创建MMKV实例 NSString *mmkvID = @"your_mmkv_id"; MMKV *mmkv = [MMKV mmkvWithID:mmkvID]; ``` 在创建MMKV实例时,需要指定一个唯一的ID来区分不同的实例。这个ID会被用作数据存储的文件名。 3. 存储数据:使用MMKV实例可以方便地存储各种类型的数据。例如,存储字符串可以使用以下代码: ``` NSString *key = @"your_key"; NSString *value = @"your_value"; [mmkv setString:value forKey:key]; ``` 除了字符串外,MMKV还支持存储其他基本数据类型(如整数、布尔值等),以及NSData对象。 4. 读取数据:使用MMKV实例可以快速读取存储数据。以下是一个读取字符串数据的示例: ``` NSString *key = @"your_key"; NSString *value = [mmkv getStringForKey:key]; ``` 同样地,你也可以使用适当的方法来读取其他类型的数据。 通过这些简单的步骤,你可以在iOS应用使用MMKV库进行持久化操作。希望这能对你有所帮助!如果有任何问题,随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值