iOS数据持久化方案

iOS数据持久化方案

在iOS开发中,有很多数据持久化的方案,接下来说一下常用的5种方案:

plist文件(属性列表)
preference(偏好设置)
NSKeyedArchiver(归档)
SQLite
CoreData

1.plist文件(属性列表)

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

- (void)plist
{
    // Document路径
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *path = [docPath stringByAppendingPathComponent:@"demo.plist"];

    // 1.写入文本
    NSString *str = @"Jerry is a good man.";
    BOOL writeSuccess = [str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
    if (writeSuccess) {
        NSLog(@"写入成功");
    }

    // 读取文本
    NSString *readStr = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%@", readStr);




    // 2.写入数组
    NSArray *array = @[@"Jerry", @"Lily"];
    writeSuccess = [array writeToFile:path atomically:YES];
    if (writeSuccess) {
        NSLog(@"写入成功");
    }

    // 读取数组
    NSArray *readArray = [NSArray arrayWithContentsOfFile:path];
    NSLog(@"%@", readArray);



    // 3.写入字典
    NSDictionary *dict = @{ @"name" : @"Jerry", @"age" : @10 };
    writeSuccess = [dict writeToFile:path atomically:YES];
    if (writeSuccess) {
        NSLog(@"写入成功");
    }

    // 读取字典
    NSDictionary *readDict = [NSDictionary dictionaryWithContentsOfFile:path];
    NSLog(@"%@", readDict);


    // 4.写入NSData
    NSData *data = [@"this is data" dataUsingEncoding:NSUTF8StringEncoding];
    writeSuccess = [data writeToFile:path atomically:YES];
    if (writeSuccess) {
        NSLog(@"写入成功");
    }

    // 读取NSData
    NSData *readDate = [NSData dataWithContentsOfFile:path];
    NSString *redaDataStr = [[NSString alloc] initWithData:readDate encoding:NSUTF8StringEncoding];
    NSLog(@"%@", redaDataStr);
}

2.preference(偏好设置)

偏好设置是专门用来保存应用程序的配置信息的,一般不要在偏好设置中保存其他数据。
如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。
偏好设置会将所有数据保存到同一个文件中。即preference目录下(沙盒根路径/Library/Preferences)的一个以此应用包名来命名的plist文件。

- (void)preference
{
    // 1.获得NSUserDefaults单例
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    // 2.写入内容
    [userDefaults setObject:@"Jerry" forKey:@"name"];
    [userDefaults setBool:YES forKey:@"sex"];
    [userDefaults setInteger:10 forKey:@"age"];
    // 3.立即同步
    [userDefaults synchronize];

    // 4.读取内容
    NSString *name = [userDefaults objectForKey:@"name"];
    BOOL sex = [userDefaults boolForKey:@"sex"];
    NSInteger age = [userDefaults integerForKey:@"age"];
    NSLog(@"%@, %d, %ld", name, sex, age);
}

3.NSKeyedArchiver(归档)

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

注意点:
必须遵循并实现NSCoding协议
保存文件的扩展名可以任意指定
继承时必须先调用父类的归档解档方法

@interface Person : NSObject <NSCoding>

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;

@end


#import "Person.h"

@implementation Person

// 归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeInt:self.age forKey:@"age"];
}

// 解档
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntForKey:@"age"];
    }
    return self;
}

@end


// 使用
- (void)archiver
{
    // Document路径
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *path = [docPath stringByAppendingPathComponent:@"archiver.plist"];

    Person *p = [[Person alloc] init];
    p.name = @"Jerry";
    p.age = 10;

    // 对象归档
    BOOL archiverSuccess = [NSKeyedArchiver archiveRootObject:p toFile:path];
    if (archiverSuccess) {
        NSLog(@"对象归档成功");
    }

    // 对象解档
    Person *unArchiverPerson = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSLog(@"name = %@, age = %d", unArchiverPerson.name, unArchiverPerson.age);

}

4.SQLite

以上方法不太适合存储大量的内容,如果数据量较大一般会使用第三方封装的数据库库, 比如FMDB.

// DBManager.h
#import "FMDB.h"

static NSString * const TABLE_BASE_DATA = @"T_BASE_DATA"; // 基础数据表

@class FMDatabase;

@interface DBManager : NSObject

/** 数据库管理类单例 */
+ (instancetype)sharedManager;

@property (nonatomic, strong) FMDatabase *db; // 数据库

@end




// DBManager.m
static DBManager *_manager;
static NSString * const DATABASE_NAME = @"qinglian.sqlite"; // 数据库表

@implementation DBManager

#pragma mark - 单例
+ (instancetype)sharedManager
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _manager = [[DBManager alloc] init];
        [_manager createDatabase];
        [_manager createTables];
    });
    return _manager;
}

+ (instancetype)alloc
{
    if (_manager) {
        NSException *exception = [NSException exceptionWithName:@"DBManager init NSException." reason:@"请使用DBManager的单例方法." userInfo:nil];
        [exception raise];
    }
    return [super alloc];
}

/** 创建数据库 */
- (void)createDatabase
{
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//    ILog(@"documentPath = %@", documentPath);
    NSString *dbPath = [documentPath stringByAppendingPathComponent:DATABASE_NAME];
    self.db = [FMDatabase databaseWithPath:dbPath];
}

/** 创建所有的表 */
- (void)createTables
{
    if (self.db && [self.db open]) {
        [self createBaseDataTable];
    } else {
        ILog(@"数据库打开失败");
    }
}

/** 创建基础数据表 */
- (void)createBaseDataTable
{
    NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (ID INTEGER PRIMARY KEY AUTOINCREMENT,FID TEXT,CHECKPOINT_CODE TEXT,INSTALLATION_CODE TEXT,INSTALLATION_TYPE TEXT,INSTALLATION_TYPE_NAME TEXT,INSTALLATION_NAME TEXT,INSTALLATION_PILE_KNO TEXT,CULVERT_STYLE TEXT,SEGMENT TEXT,SEGMENT_NAME TEXT,MAINTAIN_COMPANY TEXT,MAINTAIN_COMPANY_NAME TEXT,LONGITUDE DOUBLE,LATITUDE DOUBLE,CORRECT_LONGITUDE DOUBLE,CORRECT_LATITUDE DOUBLE)", TABLE_BASE_DATA];
    BOOL result = [_db executeUpdate:sql];
    if (!result) {
        ILog(@"创建表:TABLE_BASE_DATA失败");
    }
}


// 使用方法

/** 保存基础数据到数据库 */
+ (void)insertBaseDataToDB:(NSArray *)baseDatas
{
    FMDatabase *db = [DBManager sharedManager].db;
    if (![db open]) {
        return;
    }

    NSString *insertSql = [NSString stringWithFormat:@"INSERT INTO %@ (FID,CHECKPOINT_CODE,INSTALLATION_CODE,INSTALLATION_TYPE,INSTALLATION_TYPE_NAME,INSTALLATION_NAME,INSTALLATION_PILE_KNO,CULVERT_STYLE,SEGMENT,SEGMENT_NAME,MAINTAIN_COMPANY,MAINTAIN_COMPANY_NAME,LONGITUDE,LATITUDE,CORRECT_LONGITUDE,CORRECT_LATITUDE) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", TABLE_BASE_DATA];

    NSInteger count = baseDatas.count ? : 0;
    for (int index = 0; index < count; index++) {
        BaseDataModel *baseDataModel = baseDatas[index];

        BOOL result = [db executeUpdate:insertSql, ...];
        if (!result) {
            ILog(@"基础数据插入数据库失败");
        }
    }
    [db close];
}

5.CoreData

CoreData使用得比较少,后面补上.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值