iOS-浅谈NSUserDefaults保存数据的缺点以及改进方案:UDUserDefaultsModel

在iOS开发当中,我们难免会遇到保存数据的情况,即数据的本地永久存储。其中,NSUserDefaults是最常使用的轻量级的数据存储方式。今天小编就来简单谈一下NSUserDefaults。

    相信是个iOS程序猿都使用过NSUserDefaults来保存数据,因为实在是太过简单,只需要使用使用两行代码就能保存了,如下:

图1:NSUserDefaults的使用

使用NSUserDefaults来存取数据代码非常简单,但是很多人却并不知道苹果内部是如何保存这个key-value的。这里就简单来说一下:iOS系统是以一个.plist文件来统一管理这些使用NSUserDefaults保存的key-value的。大家可以参考你所在项目中的info.plist.

当然,我们可以验证一下:在代码当中执行NSHomeDirectory()并打印,复制,然后在Finder->前往->前往文件夹中粘贴前往,或者在终端中执行"cd 刚才复制的路径"->"open ."来前往所在沙河路径。其中NSUserDefaults就保存在/Library/Preference中。

下面就看一下我一个demo中的plist文件:

图2:NSUserDefaults保存数据的plist文件

从图2当中的.plist文件可以看到其与工程当中的info.plist文件是一样的,同时还要说一些题外话,那就是NSUserDefaults还有一些别的知识点,比如图2中的suitename等,详情请参考文档,这里不详细解释。

说使用NSUserDefaults大家都会用,但是像图1那样写代码实在是太恶心了,因为这个样子写数据根本没有统一规划,而且取值的时候十分不方便

比如做视频播放器时常用到的下面这个:

图3:允许流量播放

根据图3的显示可以知道需求:当UISwitch关闭时不允许播放视频。这是一个很常见的产品需求,但是如果按照图1的方式来写,那岂不是要在很多地方写[userDefaults objectForKey:@"key"]?所以,我们应摒弃像图1的那种方式使用NSUserDefaults。

当然,也有很多人想到了别的方法来解决图1那样写代码所带来的困扰,比如创建一个类文件来声明所有的key值等!但是那样子也难免有些麻烦,代码写起来也有些繁琐。

现在小编就来说说我的解决办法:NSUserDefaults+单例+runtime。我写的这个东西已经上传到Github,项目名称为UDUserDefaultsModel,并可以支持Cocoapods。

废话不多说,我这里就来解释UDUserDefaultsModel的思想以及用法:

1.UDUserDefaultsModel是一个单例,可以实现App内部各个类之间的数据共享。

2.继承自UDUserDefaultsModel创建一个子类,比如LCUserDefaultsModel,并在.h文件中声明一些属性,这些属性就是作为plist文件的key值存在的,如下:

图4:属性

3.在.m文件当中对每一个属性进行@dynamic操作,意为setter与getter方法由类自己实现,如下:

图5:@dynamic操作

4.如果想对属性设置默认值,那么需要重写setupDefaultValues方法,如下:

图6:默认值操作

其中,图6字典的规则是@{@"属性的字符串": @"默认值"}

5.以“name”来说,如果想要进行取值的话只需要调用[LCUserDefaultsModel userDefaultsModel].name就行,对"name"进行更改并保存到plist文件的话只需要调用[LCUserDefaultsModel userDefaultsModel].name = @"newName"就可以了。

其实说到UDUserDefaultsModel这个小型的替代系统NSUserDefaults的第三方库实现原理是:基于Objective-C的Runtime机制来重写UDUserDefaultsModel子类的属性方法,即Setter方法与Getter方法,以达到一一映射。UDUserDefaultsModel用到的Runtime的方法有:

1.objc_property_t,property_getName和property_getAttributes这三个方法是用来获取属性Property的相关信息。

2.class_addMethod是为对象增加方法,也就是属性的Setter与Getter方法。

代码小编已上传到Github,项目名称为UDUserDefaultsModel,并可以支持Cocoapods,欢迎大家支持。捎带说一句:别吝啬你手里的星星。

(注:小编已根据同样的思想来实现FMDB数据库的存取,文章链接:iOS-FMDB改进方案YIIFMDB:直接操作Model,纯面向对象,不需要写sql语句。代码小编也已经上传到Github,项目名称YIIFMDB,也已经支持Cocoapods,如果您喜欢,请别吝啬你手里的star。)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值