网站建设教程突,中国有色金属价格网,python在线免费网站,昆山张浦做网站文章目录 一. 数据持久化的目的二. iOS中数据持久化方案三. 数据持有化方式的分类1. 内存缓存2. 磁盘缓存SDWebImage缓存 四. 沙盒机制的介绍五. 沙盒目录结构1. 获取应用程序的沙盒路径2. 访问沙盒目录常用C函数介绍3. 沙盒目录介绍 六. 持久化数据存储方式1. XML属性列表2. P… 文章目录 一. 数据持久化的目的二. iOS中数据持久化方案三. 数据持有化方式的分类1. 内存缓存2. 磁盘缓存SDWebImage缓存 四. 沙盒机制的介绍五. 沙盒目录结构1. 获取应用程序的沙盒路径2. 访问沙盒目录常用C函数介绍3. 沙盒目录介绍 六. 持久化数据存储方式1. XML属性列表2. Preference 偏好设置(UserDefaults)3. NSKeyedArchiver 归档解档4. 数据库存储5. 什么是序列化和反序列化 用来做什么iOS中怎么实现序列化 一. 数据持久化的目的
快速战术提升体验。
已经加载过的数据用户下次查看的时候不需要再次从网络磁盘加载直接展示给用户。
节省用户流量
对于较大的资源数据进行缓存下次展示无需下载消耗流量。同时也降低了服务器的访问次数节省服务器的资源。
方便离线使用
用户浏览过的数据无需互联网就可以再次查看。部分功能使用解除了对于网络的依赖离线地图没有网络的时候允许用户进行操作等到下次联网的时候同步到服务器
记录用户操作
草稿对于用户需要花费较大的成本进行的操作对用户的每个步骤进行缓存当用户中断操作的时候记录下次操作直接继续上次的操作。已读内容的标记帮助用户识别哪些已读搜索记录缓存。
二. iOS中数据持久化方案
NSUserDefault简单数据快速读写。Property list 属性列表的文件存储Archiver归档。SQLite本地数据库。CoreDataCoreData 是基于 sqlite 的封装。
三. 数据持有化方式的分类
在移动端的数据持有化方式总体两类
1. 内存缓存
定义 对于使用频率比较高的数据从网络或者磁盘加载数据到内存以后使用但是不马上销毁下次直接从内存加载 内存指当前程序的运行空间缓存速度快容量小是临时存储文件用的供CPU直接读写。打开一个程序他是在内存中存储关闭程序后内存就又回到原来的空间。 例如
iOS图片初始化方法:[UIImage imageNamed:“imageName”];网络图片加载的第三方库SDWebImage
2. 磁盘缓存
定义将从网络加载的以及用户操作产生的数据写入到磁盘方便用户下次查看继续操作的时候从磁盘直接加载使用。 磁盘是程序的存储空间缓存容量大速度慢可持有化和内存的区别是磁盘可以永久的存储东西。 例如
用户输入操作内容的缓存CSDN的草稿搜索历史的缓存网络图片加载第三方 SDWebImage
SDWebImage缓存
对于SDWebImage的缓存方式SDWebImage 的图片缓存采用的是 Memory 和 Disk 双重Cache机制也就是二级缓存。 SDWebImage的缓存机制可以简单概括为第一次请求加载图片后将图片缓存在内存中并通过md5加密将图片的url进行加密处理加密处理后的值作为key将图片存储在磁盘中。当再次加载图片时先在内存缓存中寻找如果内存中找不到图片则在默认的磁盘中寻找如果还是找不到则再请求加载图片。
四. 沙盒机制的介绍
沙盒机制iOS中的沙盒机制是一种安全体系。为了保证系统安全iOS每个应用程序在安装时会创建属于自己的沙盒文件存储空间。
应用程序只能访问自身的沙盒文件不能访问其他应用程序的沙盒文件当应用程序需要向外部请求或接收数据时都需要经过权限认证否则无法获取到数据。所有的非代码文件都要保存在此例如属性文件plist、文本文件、图像、图标、媒体资源等其原理是通过重定向技术把程序生成和修改的文件定向到自身文件夹中。
五. 沙盒目录结构
每个APP的沙盒内部都有类似的目录结构 Apple的沙盒描述
1. 获取应用程序的沙盒路径
// 获取沙盒根目录路径
NSString *path NSHomeDirectory();⚠️注意每次编译代码会生成新的沙盒路径是在编译的时候所以模拟机和真机每次的沙盒路径都是不一样的。
上面的代码得到的就是当前应用程序目录的路径该目录下就是应用程序的沙盒在该目录下有4个文件夹Documents、Library、SystemData、tmp当前应用程序只能访问该目录下的文件。
Documents 目录您应该将所有的应用程序数据文件写入到这个目录下。这个目录用于存储用户数据。该路径可通过配置实现iTunes共享文件。可被iTunes备份。AppName.app 目录这是应用程序的程序包目录包含应用程序的本身。由于应用程序必须经过签名所以您在运行时不能对这个目录中的内容进行修改否则可能会使应用程序无法启动。Library 目录这个目录下有两个子目录
Preferences 目录包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.Caches 目录用于存放应用程序专用的支持文件保存应用程序再次启动过程中需要的信息。 可创建子文件夹。可以用来放置您希望被备份但不希望被用户看到的数据。该路径下的文件夹除Caches以外都会被iTunes备份。
tmp 目录这个目录用于存放临时文件保存应用程序再次启动过程中不需要的信息。该路径下的文件不会被iTunes备份。
2. 访问沙盒目录常用C函数介绍
//文件路径搜索
FOUNDATION_EXPORT NSArrayNSString * *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
该方法返回值为一个数组在iphone中由于只有一个唯一路径所以直接取数组第一个元素即可。
参数一 NSSearchPathDirectory directory指定搜索的目录名称比如这里用NSDocumentDirectory表明我们要搜索的是Documents目录。如果我们将其换成NSCachesDirectory就表示我们搜索的是Library/Caches目录。参数二 NSSearchPathDomainMask domainMask搜索主目录的位置NSUserDomainMask表示搜索的范围限制于当前应用的沙盒目录。还可以写成NSLocalDomainMask表示/Library、NSNetworkDomainMask表示/Network等。参数三 BOOL expandTilde是否获取完整的路径我们知道在iOS中的全写形式是/User/userName该值为YES即表示写成全写形式为NO就表示直接写成“~”。
下面给出上述两个参数的枚举值
typedef NS_OPTIONS(NSUInteger, NSSearchPathDomainMask) {NSUserDomainMask 1, // 用户目录 - 基本上就用这个。 NSLocalDomainMask 2, // 本地NSNetworkDomainMask 4, // 网络 NSSystemDomainMask 8, // 系统NSAllDomainsMask 0x0ffff // 所有
};//常用的NSSearchPathDirectory枚举值
typedef NS_ENUM(NSUInteger, NSSearchPathDirectory) {NSApplicationDirectory 1, // supported applications (Applications)NSDemoApplicationDirectory, // unsupported applications, demonstration versions (Demos)NSAdminApplicationDirectory, // system and network administration applications (Administration)NSLibraryDirectory, // various documentation, support, and configuration files, resources (Library)NSUserDirectory, // user home directories (Users)NSDocumentationDirectory, // Library 下的(Documentation)模拟器上没有创建NSDocumentDirectory, // documents (Documents)
};
沙盒目录获取示例 // 搜索 Document 目录NSArrayNSString * *documentPaths NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentDirectory [documentPaths firstObject];NSLog(Document Directory: %, documentDirectory);// 搜索 Document 目录 NONSArrayNSString * *documentPathsNO NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);NSString *documentDirectoryNO [documentPathsNO firstObject];NSLog(Document Directory NO: %, documentDirectoryNO);
//3. 沙盒目录介绍
Documents保存持久化数据会备份。一般用来存储需要持久化的数据。 一般我们在项目中我们会把一些用户的登录信息以及搜索历史记录等一些关键数据存储到这里。 NSArrayNSString * *documentPaths NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentDirectory [documentPaths firstObject];NSLog(Document Directory: %, documentDirectory);此文件夹是默认备份的备份到iCloud。 注iCloud的备份会通过Wi-Fi每天自动备份用户iOS设备。 我们可以在获取到的路径结尾加一个字符串来创建一个文件名 // 创建文件NSString *documentfileName [documentDirectory stringByAppendingPathComponent:data.txt];NSLog(%, documentfileName);这样我们的这个filename就是一个完整的.txt类型文件的目录了。
Library默认存放设置和其他状态信息除了caches子目录之外其他目录都会被icloud同步。 Application Support此目录包含应用程序用来运行但应对用户隐藏的文件如游戏的新关卡等文件。Caches保存应用运行时生成的需要持久化的数据一般存储体积大、不需要备份的非重要数据如网络请求的音视频与图片等的缓存。在 iOS 5.0 及以后版本中Caches 当系统磁盘空间非常低时系统可能会在极少数情况下该删除目录APP 正在运行时不会发生所以尽量保证该路径的文件在 APP 在重新运行时可以得到重新创建。Cooikes系统会自动将App中网络请求的cookie保存为文件。Preferences保存应用的所有偏好设置。UserDefaults 生成的 plist 文件就会保存该目录下。SplashBoard存储启动屏缓存缓存文件格式为 ktx本质上就是图片如果启动屏不生效的问题可以考虑从删除该路径下相关缓存文件这个角度解决。 SystemData存放系统数据无对外暴露的接口。tmp临时文件夹(系统会不定期删除里面的文件)。
六. 持久化数据存储方式
1. XML属性列表
属性列表是一种XML格式的文件拓展名为plist。
如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型就可以使用 writeToFile:atomically:方法直接将对象写到属性列表文件中举例说明
- (void)directorfile {// 获取 Document 目录NSArrayNSString * *documentPaths NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentDirectory [documentPaths firstObject];// 在 Document 目录下新建一个 test.plist 文件NSString *documentfileName [documentDirectory stringByAppendingPathComponent:data.plist];NSLog(%, documentfileName);// // 存字典将字典数据存到刚才的 test.plist 文件NSDictionary *dict {name: clearlove, boom: 4396};[dict writeToFile:documentfileName atomically:YES];// 取字典NSDictionary* msgDict [NSDictionary dictionaryWithContentsOfFile:documentfileName];NSLog(%, msgDict);
}同时进入该项目的沙盒目录中可以看到 Document 目录下多了我们刚才创建的 test.plist 文件
能看到我们存储的字典类型的文件已经存放
2. Preference 偏好设置(UserDefaults)
很多iOS应用都支持偏好设置提供了一套标准的解决方案来为应用加入偏好设置功能比如保存用户名字体大小密码是否自动登录等。
每个应用都有个NSUserDefaults实例可以通过它来存取偏好设置不需要路径。其本身的创建类似于单例模式我们在后面用不同的属性名再次申请创建会覆盖之前的数据。
NSUserDefaults简单数据快速读写不能存储自定义类型。 UserDefaults设置数据时不是立即写入而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题可以通过调用synchornize方法[defaults synchornize];强制写入。
偏好设置存储的优点
不需要关心文件名系统会自动帮你生成一个文件名。快速做键值对的存储。
- (void)preference {// 获取偏好设置对象NSUserDefaults *defaults [NSUserDefaults standardUserDefaults];// 存储数据快速键值对/[defaults setObject:clearlove forKey:username];[defaults setObject:4396-2016 forKey:password];[defaults synchronize];// 需要验证账号密码的地方获取偏好设置对象NSUserDefaults *defaultsA [NSUserDefaults standardUserDefaults];NSString *name [defaultsA objectForKey:username];NSString *password [defaultsA objectForKey:password];NSLog(name:% password:%, name, password);
} 3. NSKeyedArchiver 归档解档
NSKeyedArchiver(归档)归档一般都是保存自定义对象的时候使用归档。因为plist文件不能够保存自定义对象。如果一个字典中保存有自定义对象如果把这个对象写入到文件当中它是不会生成 plist文件的。如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型可以直接用NSKeyedArchiver进行归档和恢复。
但是在我们使用归档之前我们必须得遵守NSSecureCoding协议才行老版本只需要遵循NSCoding实现其归档和解档的方法就行但是iOS13更新之后就不行了我们就必须的遵守NSSecureCoding协议NSSecureCoding协议也遵循了原来NSCoding这个协议不过我们还需要遵循它的一个supportsSecureCoding方法这样我们才能归档成功。
因为NSSecureCoding协议也遵循了原来NSCoding这个协议所以他也就有了- (void)encodeWithCoder:(NSCoder *)coder方法和- (id)initWithCoder:(NSCoder *)coder方法
(void)encodeWithCoder:(NSCoder *)coder方法 每次归档对象时都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量。可以使用encodeObject:forKey:方法归档实例变量。 (id)initWithCoder:(NSCoder *)coder方法 每次从文件中会恢复解码对象时都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量可以使用decodeObject:forKey方法解码实例变量。 除了这两个方法之外NSSecureCoding协议还有 (BOOL)supportsSecureCoding方法只有当这个方法为YES的时候才可以归档成功。
利用归档解档尝试存储一个Person对象
#import Foundation/Foundation.hNS_ASSUME_NONNULL_BEGINinterface Person : NSObjectNSSecureCoding
property (nonatomic, strong) NSString *name;
property (assign) int age;
- (void)saveData;
- (void)readData;end#import Person.himplementation Person
- (void)encodeWithCoder:(NSCoder *)coder {[coder encodeObject:_name forKey:name];[coder encodeInt:_age forKey:age];
}
- (id)initWithCoder:(NSCoder *)coder {if (self [super init]) {_name [coder decodeObjectForKey:name];_age [coder decodeIntForKey:age];}return self;
}
// 返回YES才能成功归档(BOOL)supportsSecureCoding {return YES;
}- (void)saveData {Person *p [[Person alloc] init];p.name clearlove;p.age 24;NSError *error;// 2.归档模型对象// 3.获得 Documents 的全路径NSString *docu [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];// 4.获得新文件的全路径即新建一个 person.data 文件来存储我们要归档的数据NSString *path [docu stringByAppendingString:/person.plist];NSLog(%, path);// 5.将对象封装为 Data 数据并归档NSData *data [NSKeyedArchiver archivedDataWithRootObject:p requiringSecureCoding:YES error:error];if (error) {NSLog(sodufosuf%, error);}[data writeToFile:path atomically:YES];
}
// 读档将数据从文件中读出
- (void)readData {NSError *error;// 1.获得 Documents 的全路径NSString *docu [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];// 2.获得文件的全路径即获取我们要解档文件的路径NSString *path [docu stringByAppendingString:/person.plist];// 3.从 path 路径中获取 Data 数据NSData *unData [NSData dataWithContentsOfFile:path];// 4.从文件中读取Person对象Person *person (Person *)[NSKeyedUnarchiver unarchivedObjectOfClass:[Person class] fromData:unData error:error];// 打印结果NSLog(name: % age: %d,person.name, person.age);
}
end
打印文件路径 查看多了一个person. Document多了一个plist文件
⚠️注意 我们一定要遵守NSSecureCoding协议并实现它的归档解档方法以及 (BOOL)supportsSecureCoding方法
4. 数据库存储
SQLite
是目前主流的嵌入式关系型数据库其最主要的特点就是轻量级、跨平台当前很多嵌入式操作系统都将其作为数据库首选。
CoreData
CoreData是iOS5之后才出现的一个框架本质上是对SQLite的一个封装它提供了对象-关系映射(ORM)的功能即能够将OC对象转化成数据保存在SQLite数据库文件中也能够将保存在数据库中的数据还原成OC对象在这个过程中不需要手动编写任何SQL语句CoreData封装了数据库的操作过程以及数据库中数据和OC对象的转换过程。通过CoreData管理应用程序的数据模型可以极大程度减少需要编写的代码数量。
FMDB
是一个处理数据存储的第三方框架框架是对sqlite的封装整个框架非常轻量级但又不失灵活性而且更加面向对象。
SQLite和CoreData的区别
CoreData可以在一个对象更新时其关联的对象也会随着更新相当于你更新一张表时其关联的其他表的也会随着更新。CoreData供更简单的性能管理机制可以限制查询记录的总数这个类会自动更新其缓存。多表查询方面CoreData没有SQL直观没有类似外连接左连接等操作。
5. 什么是序列化和反序列化 用来做什么
序列化把对象转化为字节序列的过程反序列化把字节序列恢复成对象作用把对象写到文件或者数据库中并且读取出来
iOS中怎么实现序列化
在iOS实际开发中我们也会使用到序列化归档就是我们在iOS开发中使用序列化的场景 在iOS中一个自定义对象是无法直接存入到文件中的必须先转化成二进制流才行。从对象到二进制数据的过程我们一般称为对象的序列化(Serialization)也称为归档(Archive)。同理从二进制数据到对象的过程一般称为反序列化或者反归档(解档)。