Skip to content

Latest commit

 

History

History
177 lines (105 loc) · 5.93 KB

数据存储面试要点.md

File metadata and controls

177 lines (105 loc) · 5.93 KB

NSUserDefaults

使用场景

  • NSUserDefaults一般用来存储一些简单的App配置。比如存储用户姓名、uid这类轻量的数据。
  • 用于处于同一App group不同App之间共享数据,用户extension和宿主App之间共享数据。
  • 一般通过调用如下方法实现增删改查功能
- (void)setObject:(nullable id)value forKey:(NSString *)defaultName; //设置defaultName对应的值为value,如果存在defaultName,则执行更新操作,否则执行增加操作
- (nullable id)objectForKey:(NSString *)defaultName; //查询defaultName对应的值,没有返回nil
- (void)removeObjectForKey:(NSString *)defaultName; //删除defaultName对应的指

  • NSUserDefaults不能存储自定义Model。

封装NSUserDefaults

  • 在项目中,我们一般会建一个UserDefaults管理类,用来管理存储NSUserDefaults。比如建立一个AppUserDefaultsMgr类
@interface AppUserDefaultsMgr : NSObject

+ (instancetype)sharedInstance;

@property (nonatomic, copy)NSString* name; //通过@dynamic自定义setter和getter
@property (nonatomic, copy)NSString* uid; //通过@dynamic自定义setter和getter

@end

@dynamic name; 
@dynamic uid;

@implementation AppUserDefaultsMgr

+ (instancetype)sharedInstance{

    static id  s_singleton = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        s_singleton = [[[self class] alloc] init];
    });

    return s_singleton;
}

- (NSString*)name{

    return [NSUserDefaults stringForKey:@"name"];
}

- (NSString*)setName:(NSString*)name{

    return [NSUserDefaults setObject:name forKey:@"name"];
}

- (NSString*)uid{

    return [NSUserDefaults stringForKey:@"uid"];
}

- (NSString*)setUid:(NSString*)uid{

    return [NSUserDefaults setObject:uid forKey:@"uid"];
}

然后业务方如下调用:

[AppUserDefaultsMgr sharedInstance].name = @"akon";
NSLog(@"name", [AppUserDefaultsMgr.sharedInstance].name);

此种方式缺点是:每定义一个属性(比如name和uid),都需要手动的去写下setter和getter方法。大量重复而类似的代码,相当难看。能不能不手写setter和getter方法,然后像使用属性一样去操作NSUserDefaults呢? 可以借助(GVUserDefaults)[https://github.com/gangverk/GVUserDefaults]来实现。GVUserDefaults的实现思路是通过runtime动态地为属性添加setter和getter方法。让AppUserDefaultsMgr继承GVUserDefaults即可,name和uid不要手写setter和getter方法,节省了大量代码。

@interface AppUserDefaultsMgr : GVUserDefaults

+ (instancetype)sharedInstance;

@property (nonatomic, copy)NSString* name; //通过@dynamic自定义setter和getter
@property (nonatomic, copy)NSString* uid; //通过@dynamic自定义setter和getter

@end

@dynamic name; 
@dynamic uid;

@implementation AppUserDefaultsMgr

+ (instancetype)sharedInstance{

    static id  s_singleton = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        s_singleton = [[[self class] alloc] init];
    });

    return s_singleton;
}

Archive

Archive可以用来存储model,如果一个model要用Archive存取,需要实现NSCoding协议。项目中使用的相对少点,如果要存储model,可以先把Model转成json字符串存到NSUserDefaults里面。

plist存储方式

像NSString、NSDictionary等类都可以直接存调用writeToFile:atomically:方法存储到plist文件中。存储格式为XML。

数据库存储

CoreData

CoreData是苹果开发的orm数据存储库。CoreData上手成本比较高,具体使用参考iOS-CoreData详解与使用

FMDB

FMDB是基于sqlite封装的轻量级数据库,使用简单,用的人很多。

YTKKeyValueStore

YTKKeyValueStore基于FMDB封装的k-v存储库。

YYCache

YYCache基于sqlite封装的cache库,支持内存缓存和磁盘缓存。

WCDB

WCDB是微信开源的基于sqlite封装的数据存储库。 高效、完整、易用的移动数据库框架。基于SQLCipher,支持iOS、macOS、Android。

  • 高效。支持多线程高并发:读与读、读与写并发执行,写与写串行执行。
  • 完整。支持数据库加密、损坏修复、反注入。
  • 易用。通过ORM、WINQ,支持一句代码即可将数据取出并组合为object。 强烈推荐使用。

数据库操作

常用crud语句书写

创建表、给表增加字段、插入、删除、更新、查询SQL怎么写。尤其是查询操作,可以考察order by, group by ,distinct, where匹配以及联表查询等技巧。

索引、事务等常用优化技巧

通过在常用查询列上建立索引来加快查询速度。索引适合在查询多于插入的场景下使用。 设计到批量操作,比如批量删除,可以使用事务,这样效率更高,而且事务失败还能回滚

防止SQL注入

不要裸写SQL语句,通过使用ORM数据库比如WCDB来操作数据库能防止SQL注入。

数据库加密

sqllite原生支持数据库文件加密,如果要对记录进行加密需要自己处理。

数据库版本迁移

用CoreData和FMDB,数据迁移需要自己定义数据库版本号,自己实现迁移逻辑。WCDB已经给你实现了数据库迁移。

如何选择

强烈建议大家使用NSUserDefaults来存储简单的App配置,使用WCDB进行数据库存储和KV存储。

资料推荐

如果你正在跳槽或者正准备跳槽不妨动动小手,添加一下咱们的交流群931542608来获取一份详细的大厂面试资料为你的跳槽多添一份保障。