• iOS——持久化


    数据持久化

    iOS中的永久存储,也就是在关机重新启动设备,或关闭应用时不会丢失数据。在实际开发中,往往需要持有存储数据的。

    数据持久化的优点:

    1. 快速展示,提升体验
      已经加载过的数据,用户下次查看的时候,不需要再次从网络(磁盘)加载,直接展示给用户
    2. 节省用户流量(节省服务器资源)
      对于较大的资源数据进行缓存,下次展示无需下载消耗流量,同时降低了服务器的访问次数,节约服务器资源
    3. 离线使用。
    4. 记录用户操作

    iOS中数据持久化的方案

    • NSUserDefault 简单数据快速读写
    • Property list (属性列表)文件存储
    • Archiver (归档)
    • SQLite 本地数据库
    • CoreData

    数据持有化方式分类

    在移动端的数据持有化方式总体有两类

    内存缓存

    定义: 对于使用频率比较高的数据,从网络或磁盘加载数据到内存以后,使用后并不马上销毁,下次使用直接从内存加载。
    内存指当前程序的运行空间,缓存速度快容量小,是临时存储文件用的,供CPU直接读写。打开一个程序,他是在内存中存储,关闭程序后内存就又回到原来的空间空间。
    案例

    • iOS系统图片加载——[UIImage imageNamed:@“imageName”]
    • 网络图片加载三方库 SDWebImage

    磁盘缓存

    定义:将从网络加载的,用户操作产生的数据写入到磁盘,用户下次查看、继续操作时,直接从磁盘加载使用
    磁盘是程序的存储空间,缓存容量大、速度慢、可持有化。与内存不同的是磁盘是永久存储东西的。
    案例

    • 用户输入内容草稿缓存
    • 搜索历史缓存
    • 网络图片加载三方库 SDWebImage

    iOS沙盒机制

    iOS中的沙盒机制是一种安全体系。为了保证系统安全,iOS每个应用程序在安装时,会创建属于自己的沙盒文件(存储空间)。应用程序只能访问自身的沙盒文件,不能访问其他应用程序的沙盒文件,当应用程序需要向外部请求或接收数据时,都需要经过权限认证,否则,无法获取到数据。所有的非代码文件都要保存在此,例如属性文件plist、文本文件、图像、图标、媒体资源等,其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中。

    沙盒目录

    每个APP的沙盒中都有以下目录结构。
    在这里插入图片描述

    Application(应用程序包):

    包含了所有的资源文件和和可执行文件,上架前经过数字签名,上架后不可修改。

    Documents:

    文档目录,要保存程序生成的数据,会自动被分到iCloud中。保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录。(注意点:不要保存从网络上下载的文件,否则会无法上架!)

    Library:

    1.用户偏好,使用 NSUserDefault 直接读写!
    2.如果要想数据及时写入磁盘,还需要调用一个同步方法
    3.保存临时文件,“后续需要使用”,例如:缓存图片,离线数据(地图数据
    系统不会清理 cache 目录中的文件,就要求程序开发时,“必须提供 cache 目录的清理解决方案”
    4.Caches:存放体积大又不需要备份的数据
    5.Preference:保存应用的所有偏好设置,iCloud会备份设置信息

    Tmp:

    临时文件,系统会自动清理。重新启动就会清理。保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录。

    1. 存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能
    2. 保存临时文件,“后续不需要使用”
    3. tmp 目录中的文件,系统会自动清理
    4. 重新启动手机,tmp 目录会被清空
    5. 系统磁盘空间不足时,系统也会自动清理

    获取沙盒目录的常见获取方式

    • 沙盒根目录:
     // 获取沙盒根目录路径
        NSString *path = NSHomeDirectory();
        NSLog(@"当前APP沙盒根目录路径为:%@", path);
    
    • 1
    • 2
    • 3

    注意: 每次编译代码会生成新的沙盒路径,注意是编译不是启动,所以模拟机或者真机运行,每次运行所得到的沙盒路径都是不一样的,线上版本app真机不会生成新的沙盒路径。
    在这里插入图片描述

    在这里插入图片描述

    访问沙盒目录常用C函数介绍

    //文件路径搜索
    FOUNDATION_EXPORT NSArray<NSString *> *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
    
    • 1
    • 2

    该方法返回值为一个数组,在iphone中由于只有一个唯一路径,所以直接取数组第一个元素即可.

    • 参数1:指定搜索的目录名称,比如这里用NSDocumentDirectory表明我们要搜索的是Documents目录。如果我们将其换成NSCachesDirectory就表示我们搜索的是Library/Caches目录。
    typedef NS_ENUM(NSUInteger, NSSearchPathDirectory) {
        NSApplicationDirectory = 1,             // supported applications (Applications)
        NSDemoApplicationDirectory,             // unsupported applications, demonstration versions (Demos)
        NSDeveloperApplicationDirectory,        // developer applications (Developer/Applications). DEPRECATED - there is no one single Developer directory.
        NSAdminApplicationDirectory,            // system and network administration applications (Administration)
        NSLibraryDirectory,                     // various documentation, support, and configuration files, resources (Library)
        NSDeveloperDirectory,                   // developer resources (Developer) DEPRECATED - there is no one single Developer directory.
        NSUserDirectory,                        // user home directories (Users)
        NSDocumentationDirectory,               // documentation (Documentation)
        NSDocumentDirectory,                    // documents (Documents)
        NSCoreServiceDirectory,                 // location of CoreServices directory (System/Library/CoreServices)
        NSAutosavedInformationDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 11,   // location of autosaved documents (Documents/Autosaved)
        NSDesktopDirectory = 12,                // location of user's desktop
        NSCachesDirectory = 13,                 // location of discardable cache files (Library/Caches)
        NSApplicationSupportDirectory = 14,     // location of
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 参数2 domainMask:NSSearchPathDomainMask类型,搜索主目录的位置,NSUserDomainMask表示搜索的范围限制于当前应用沙盒目录。NSLocalDomainMask(表示/Library)
    typedef NS_OPTIONS(NSUInteger, NSSearchPathDomainMask) {
        NSUserDomainMask = 1,       // user's home directory --- place to install user's personal items (~)// 
        NSLocalDomainMask = 2,      // local to the current machine --- place to install items available to everyone on this machine (/Library)
        NSNetworkDomainMask = 4,    // publically available location in the local area network --- place to install items available on the network (/Network)
        NSSystemDomainMask = 8,     // provided by Apple, unmodifiable (/System)
        NSAllDomainsMask = 0x0ffff  // all domains: all of the above and future items
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 参数3 expandTilde:是否获取完整路径,在iOS中全写形式是/User/userName,该值为yes表示全写形式,为no就直接写成~
      在这里插入图片描述
      在这里插入图片描述

    持久化方案实现

    Preferences偏好设置(UserDefaults)

    简单数据快速读写,不能存储自定义类型
    UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法[defaults synchornize];强制写入。
    偏好设置存储的优点:
    不需要关心文件名,系统会自动帮你生成一个文件名
    快速做键值对的存储
    在这里插入图片描述

    plist文件

    在这里插入图片描述
    如果对象是NSStringNSDictionaryNSArrayNSDataNSNumber等类型,就可以使用
    writeToFile:atomically:方法直接将对象写到属性列表文件中
    在这里插入图片描述

    Archiver (归档)

    Archiver是持久化数据的一种方式,他跟 Plist的区别在于他能持久化自定义对象。但他没Plist那么方便。
    Archiver默认能持久化的数据有NSNumber,NSArray,NSDictionary,NSString,NSData,因为这几个对象已经实现了
    协议。假设我们要实现一个对象的Archiver持久化 ,也必须实现该对象。iOS13之后,我们就必须的遵守NSSecureCoding协议,NSSecureCoding协议也遵循了原来NSCoding这个协议,不过我们还需要遵循它的一个supportsSecureCoding方法,这样我们才能归档成功。

    // 归档
    -(void)testArchiver {
        NSArray* array = [NSArray arrayWithObjects:@"zhangsan",@"wangwu",@"list",nil];
           
            // NSHomeDirectory 获取根目录 stringByAppendingPathComponent 添加储存的文件名
            
             NSString* filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.src"];
             BOOL success = [NSKeyedArchiver archiveRootObject:array toFile:filePath];
             if(success){
                 NSLog(@"保存成功");
             }else {
                 NSLog(@"未保存");
             }
    }
    // 解档
    - (void)testReturn {
        NSString* filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.src"];
        NSArray *array = [[NSArray alloc] init];
        array = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        NSLog(@"%@",array);
    }
    + (BOOL)supportsSecureCoding {
            return YES;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    数据库存储

    • SQLite
      是目前主流的嵌入式关系型数据库,其最主要的特点就是轻量级、跨平台,当前很多嵌入式操作系统都将其作为数据库首选。
    • CoreData
      CoreData是iOS5之后才出现的一个框架,本质上是对SQLite的一个封装,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象,在这个过程中不需要手动编写任何SQL语句,CoreData封装了数据库的操作过程,以及数据库中数据和OC对象的转换过程。通过CoreData管理应用程序的数据模型,可以极大程度减少需要编写的代码数量
    • FMDB
      是一个处理数据存储的第三方框架,框架是对sqlite的封装,整个框架非常轻量级但又不失灵活性,而且更加面向对象。

    什么是序列化和反序列化,用来做什么?

    • 序列化:把对象转化为字节序列的过程
    • 反序列化:把字节序列恢复成对象
    • 作用:把对象写到文件或者数据库中,并且读取出来
  • 相关阅读:
    Vue 3是一个错误,我们不应该再犯。
    JavaWeb概念视频笔记
    屋顶太阳能光伏系统的性能分析指标研究
    Python人工智能气象、大气污染扩散Calpuff模型、WRF/Chem模式、未来大气污染变化模拟
    实现无公网IP环境下远程访问本地Jupyter Notebook服务的方法及端口映射
    Qt6中使用Qt Charts
    HTTP Host 头攻击 原理以及修复方法
    基于Istio服务治理网格的SpringCloud大型微服务项目部署流程
    科学并不等于实验 南瓜科学给出全新答案
    机器学习算法面试知识点解读
  • 原文地址:https://blog.csdn.net/chabuduoxs/article/details/126196431