【IOS学习】 IOS的四种数据存储方式及优劣

时间:2021-04-19 08:20:25

iOS有四种常用数据存储方式: 
第一种方法:用NSUserDefaults存储配置信息 
NSUserDefaults被设计用来存储设备和应用的配置信息,它通过一个工厂方法返回默认的、也是最常用到的实例对象。这个对象中储存了系统中用户的配置信息,开发者可以通过这个实例对象对这些已有的信息进行修改,也可以按照自己的需求创建新的配置项。他实际上是存储于文件沙盒中的一个.plist文件,并且没有被系统加密,只是ios6以后不是存于常用的文档目录下,所以不破解系统是看不到该文件的。所以该种方法储存的数据并不是很很安全,若想存储安全还是靠你自己的加密算法。一般这种方法存储少量信息,若是存储大量信息,如存储一百个数据你怎么记录键值啊?它可以在代码的任何部分存储数据,你不知道你整个应用存储了多少数据,所以它不利于统一管理,不建议采用。就是你把存储数据的函数统一放在一个文件中便于管理,但是你不能保证别人也遵循你的意志与做法啊,所以最好用第二种对象存储比较好。所有的机密数据都存储在一个对象中,一看就知道了,删除和添加很方便,便于管理。作为合格的码农,别说那么多应该和不该是,业务逻辑决定不会有这样的数据这样苍白的话,要从机制上杜绝各种异常数据。如:对象存储,在所有函数入口对参数进行合法性判断。

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">+ (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)setUserDefaultsValue:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>)value key:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)key
{
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSUserDefaults</span> *userDefaults = [<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSUserDefaults</span> standardUserDefaults];

[userDefaults setObject:value forKey:key];
[[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSUserDefaults</span> standardUserDefaults] synchronize];

}

+ (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>)objectForKey:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)key
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSUserDefaults</span> standardUserDefaults] objectForKey:key];
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

调用: 
NSString *selectedKey = [[NSUserDefaults standardUserDefaults] objectForKey:@”selectedKey”];

第二种方法:方法用CoreData对象存储。像MFC等称之为序列化和反序列化,MFC是实际上存于应用对应的数据库表单中。他实际上是把文件存在文件沙盒中,对应的是文档目录,所以用户可以看到该文件,系统对该文件进行了加密。一般文件名的后缀是.archiver。这样对那些不想设计加密算法,又想加密数据的人是个不错的福音。 
一个支持持久化的,对象图和生命周期的自动化管理方案。它的数据也是存于系统数据库中应用对应的表中,所以可以用于存储机密数据(如:用户名和密码),可以存储各种数据。一般超大的数据,如:图片,行程记录存在文件沙盒中,不适合用这种对象存储,除非你的行程数据很机密,并且数据不可能超大,才考虑对象存储。严格意义上说CoreData是一个管理方案,他的持久化可以通过SQLite、XML或二进制文件储存。如官方定义所说,CoreData的作用远远不止储存数据这么简单,它可以把整个应用中的对象建模并进行自动化的管理。他和微软的MFC::CArchive实现对象的持久化和反持久化一样只能支持支持具有序列化的函数,把对象分解成基本数据类型的类型的持久化,如字符串,整形数字,浮点型数据,字符。由于持久化的对象数据都在一个对象中,所以他利于数据管理。所以采用CoreData存储数据就不需要采用NSUserDefaults数据存储数据了。 
-(id)initWithDictionary:(NSDictionary*)dic 

if (self=[super init]) 

self.sex=[dic[@”sex”] intValue]; 
self.driverYear=[dic[@”driverYear”] intValue]; 
}

return self;

}

-(void)encodeWithCoder:(NSCoder *)aCoder 

[aCoder encodeObject:[NSNumber numberWithInt:self.driverId] forKey:@”id”]; 
[aCoder encodeObject:[NSNumber numberWithInt:self.sex] forKey:@”sex”];


-(id)initWithCoder:(NSCoder *)aDecoder 

if (self=[super init]) 

self.sex=[[aDecoder decodeObjectForKey:@”sex”] intValue]; 
self.driverYear=[[aDecoder decodeObjectForKey:@”driverYear”] intValue]; 

return self; 
}

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//清理用户信息</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)clearUserInfo{
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>) lastObject];
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *path = [documents stringByAppendingPathComponent:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"user.archiver"</span>];
User *user;
[NSKeyedArchiver archiveRootObject:user toFile:path];
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保存</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)saveinfo:(User *)user
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span> != user)
{
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>) lastObject];
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *path = [documents stringByAppendingPathComponent:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"user.archiver"</span>];
[NSKeyedArchiver archiveRootObject:user toFile:path];
}
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//得到用户信息</span>
-(User *)getUserinfo;
{
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>) lastObject];
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *path = [documents stringByAppendingPathComponent:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"user.archiver"</span>];<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//拓展名可以自己随便取</span>
User *user = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> user;
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//从对象沙盒中读文件</span>
User*user=[[GlobalShare getGlobalShare] getUserinfo];

[GlobalShare getGlobalShare]<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.user</span> = user;
[GlobalShare getGlobalShare]<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.user</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.orderLastLatitude</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 保存在本地</span>
[[GlobalShare getGlobalShare] saveinfo:user];
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul>

第三种方法:文件沙盒存储 
主要存储非机密数据,大的数据。如:下载的图片,没有键值的分行记录。注意若系统被破解了你的沙盒中的文件可以被别人获得。这种方法操作很简单。不知道为何很多介绍数据存储的文章为何把这种最常见的,最简单直接的方式给忽略了。文件沙盒常用的文件一般存储于文档文件目录(NSDocumentDirectory非破解系统,用户可以直接看到)和缓存文档目录(NSCachesDirectory非破解系统,用户不可见)。看来天下文章一大抄啊! 
//写文件 
+ (void)writeToDocumentWithImageData:(NSData )data name:(NSString )fileName 

NSString *path = [self filePath:fileName];

[data writeToFile:path atomically:YES];


//获取文件路径 
+ (NSString*)filePath:(NSString*)fileName { 
NSArray* myPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString* myDocPath = [myPaths objectAtIndex:0]; 
NSString* filePath = [myDocPath stringByAppendingPathComponent:fileName]; 
return filePath; 

第四种方法:数据库存储 
iOS的SDK里预置了SQLite的库,开发者可以自建SQLite数据库。SQLite每次写入数据都会产生IO消耗,把数据归档到相应的文件。 
SQLite擅长处理的数据类型其实与NSUserDefaults差不多,也是基础类型的小数据,只是从组织形式上不同。开发者可以以关系型数据库的方式组织数据,使用SQL DML来管理数据。 一般来说应用中的格式化的文本类数据可以存放在数据库中,尤其是类似聊天记录、Timeline等这些具有条件查询和排序需求的数据。 
无论你采用系统自带的还是用的SQLight第三方库的数据存储本质都数据库存储,没必要再另外分类。数据存储稍微麻烦,并且存储的速度较慢,只有真正需要用到的地方才采用这种方式,如:聊天记录,地图地理信息查询。