当前位置: 首页 > news >正文

【iOS】iOS持久化

文章目录

  • 一. 数据持久化的目的
  • 二. iOS中数据持久化方案
  • 三. 数据持有化方式的分类
    • 1. 内存缓存
    • 2. 磁盘缓存
      • SDWebImage缓存
  • 四. 沙盒机制的介绍
  • 五. 沙盒目录结构
    • 1. 获取应用程序的沙盒路径
    • 2. 访问沙盒目录常用C函数介绍
    • 3. 沙盒目录介绍
  • 六. 持久化数据存储方式
    • 1. XML属性列表
    • 2. Preference 偏好设置(UserDefaults)
    • 3. NSKeyedArchiver 归档解档
    • 4. 数据库存储
    • 5. 什么是序列化和反序列化? 用来做什么?
      • iOS中怎么实现序列化?

一. 数据持久化的目的

  1. 快速战术,提升体验。
  • 已经加载过的数据,用户下次查看的时候不需要再次从网络磁盘加载,直接展示给用户。
  1. 节省用户流量
  • 对于较大的资源数据进行缓存,下次展示无需下载消耗流量。
  • 同时也降低了服务器的访问次数,节省服务器的资源。
  1. 方便离线使用
  • 用户浏览过的数据无需互联网就可以再次查看。
  • 部分功能使用解除了对于网络的依赖(离线地图)
  • 没有网络的时候允许用户进行操作,等到下次联网的时候同步到服务器
  1. 记录用户操作
  • 草稿:对于用户需要花费较大的成本进行的操作,对用户的每个步骤进行缓存,当用户中断操作的时候记录,下次操作直接继续上次的操作。
  • 已读内容的标记,帮助用户识别哪些已读
  • 搜索记录缓存。

二. iOS中数据持久化方案

  • NSUserDefault:简单数据快速读写。
  • Property list: 属性列表的文件存储
  • Archiver:归档。
  • SQLite:本地数据库。
  • CoreDataCoreData 是基于 sqlite 的封装。

三. 数据持有化方式的分类

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

1. 内存缓存

  • 定义: 对于使用频率比较高的数据,从网络或者磁盘加载数据到内存以后,使用但是不马上销毁,下次直接从内存加载

内存指当前程序的运行空间,缓存速度快容量小,是临时存储文件用的,供CPU直接读写。打开一个程序,他是在内存中存储,关闭程序后内存就又回到原来的空间。

例如:

  • iOS图片初始化方法:[UIImage imageNamed:@“imageName”];
  • 网络图片加载的第三方库SDWebImage

2. 磁盘缓存

  • 定义:将从网络加载的以及用户操作产生的数据写入到磁盘方便用户下次查看,继续操作的时候从磁盘直接加载使用。

磁盘是程序的存储空间,缓存容量大,速度慢,可持有化,和内存的区别是磁盘可以永久的存储东西。

例如:

  • 用户输入操作内容的缓存(CSDN的草稿)
  • 搜索历史的缓存
  • 网络图片加载第三方 SDWebImage

SDWebImage缓存

对于SDWebImage的缓存方式:SDWebImage 的图片缓存采用的是 MemoryDisk 双重Cache机制,也就是二级缓存。 SDWebImage的缓存机制可以简单概括为:第一次请求加载图片后将图片缓存在内存中,并通过md5加密将图片的url进行加密处理,加密处理后的值作为key,将图片存储在磁盘中。当再次加载图片时,先在内存缓存中寻找,如果内存中找不到图片,则在默认的磁盘中寻找,如果还是找不到,则再请求加载图片。
在这里插入图片描述

四. 沙盒机制的介绍

沙盒机制:iOS中的沙盒机制是一种安全体系。为了保证系统安全,iOS每个应用程序在安装时,会创建属于自己的沙盒文件(存储空间)。

  1. 应用程序只能访问自身的沙盒文件,不能访问其他应用程序的沙盒文件,当应用程序需要向外部请求或接收数据时,都需要经过权限认证,否则,无法获取到数据。所有的非代码文件都要保存在此,
  2. 例如属性文件plist、文本文件、图像、图标、媒体资源等,其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中。

五. 沙盒目录结构

每个APP的沙盒内部都有类似的目录结构 Apple的沙盒描述
请添加图片描述

1. 获取应用程序的沙盒路径

// 获取沙盒根目录路径
NSString *path = NSHomeDirectory();

请添加图片描述
⚠️注意:每次编译代码会生成新的沙盒路径,是在编译的时候,所以模拟机和真机每次的沙盒路径都是不一样的。
请添加图片描述

上面的代码得到的就是当前应用程序目录的路径,该目录下就是应用程序的沙盒,在该目录下有4个文件夹:DocumentsLibrarySystemDatatmp当前应用程序只能访问该目录下的文件。

  1. Documents 目录:您应该将所有的应用程序数据文件写入到这个目录下。这个目录用于存储用户数据。该路径可通过配置实现iTunes共享文件。可被iTunes备份。
  2. AppName.app 目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。
  3. Library 目录:这个目录下有两个子目录:
  • Preferences 目录:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.
  • Caches 目录:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。
    可创建子文件夹。可以用来放置您希望被备份但不希望被用户看到的数据。该路径下的文件夹,除Caches以外,都会被iTunes备份。
  1. tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。该路径下的文件不会被iTunes备份。

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

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

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

  1. 参数一 NSSearchPathDirectory directory:指定搜索的目录名称,比如这里用NSDocumentDirectory表明我们要搜索的是Documents目录。如果我们将其换成NSCachesDirectory就表示我们搜索的是Library/Caches目录。
  2. 参数二 NSSearchPathDomainMask domainMask:搜索主目录的位置,NSUserDomainMask表示搜索的范围限制于当前应用的沙盒目录。还可以写成NSLocalDomainMask(表示/Library)、NSNetworkDomainMask(表示/Network)等。
  3. 参数三 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 目录NSArray<NSString *> *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentDirectory = [documentPaths firstObject];NSLog(@"Document Directory: %@", documentDirectory);// 搜索 Document 目录 NONSArray<NSString *> *documentPathsNO = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);NSString *documentDirectoryNO = [documentPathsNO firstObject];NSLog(@"Document Directory NO: %@", documentDirectoryNO);
//

请添加图片描述

3. 沙盒目录介绍

  • Documents:保存持久化数据,会备份。一般用来存储需要持久化的数据。
    一般我们在项目中,我们会把一些用户的登录信息以及搜索历史记录等一些关键数据存储到这里。
 NSArray<NSString *> *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

如果对象是NSStringNSDictionaryNSArrayNSDataNSNumber等类型,就可以使用
writeToFile:atomically:方法直接将对象写到属性列表文件中,举例说明:

- (void)directorfile {// 获取 Document 目录NSArray<NSString *> *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文件的。如果对象是NSStringNSDictionaryNSArrayNSDataNSNumber等类型,可以直接用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.h>NS_ASSUME_NONNULL_BEGIN@interface Person : NSObject<NSSecureCoding>
@property (nonatomic, strong) NSString *name;
@property (assign) int age;
- (void)saveData;
- (void)readData;@end
#import "Person.h"@implementation 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的封装,整个框架非常轻量级但又不失灵活性,而且更加面向对象。

SQLiteCoreData的区别:

  • CoreData可以在一个对象更新时,其关联的对象也会随着更新,相当于你更新一张表时,其关联的其他表的也会随着更新。
  • CoreData供更简单的性能管理机制,可以限制查询记录的总数,这个类会自动更新其缓存。
  • 多表查询方面,CoreData没有SQL直观,没有类似外连接,左连接等操作。

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

  • 序列化:把对象转化为字节序列的过程
  • 反序列化:把字节序列恢复成对象
  • 作用:把对象写到文件或者数据库中,并且读取出来

iOS中怎么实现序列化?

在iOS实际开发中,我们也会使用到序列化,归档就是我们在iOS开发中使用序列化的场景!
在iOS中一个自定义对象是无法直接存入到文件中的,必须先转化成二进制流才行。从对象到二进制数据的过程我们一般称为对象的序列化(Serialization),也称为归档(Archive)。同理,从二进制数据到对象的过程一般称为反序列化或者反归档(解档)。

相关文章:

【iOS】iOS持久化

文章目录 一. 数据持久化的目的二. iOS中数据持久化方案三. 数据持有化方式的分类1. 内存缓存2. 磁盘缓存SDWebImage缓存 四. 沙盒机制的介绍五. 沙盒目录结构1. 获取应用程序的沙盒路径2. 访问沙盒目录常用C函数介绍3. 沙盒目录介绍 六. 持久化数据存储方式1. XML属性列表2. P…...

基于Javaweb+Vue3实现淘宝卖鞋前后端分离项目

前端技术栈&#xff1a;HTMLCSSJavaScriptVue3 后端技术栈&#xff1a;JavaSEMySQLJDBCJavaWeb 文章目录 前言1️⃣登录功能登录后端登录前端 2️⃣商家管理查询商家查询商家后端查询商家前端 增加商家增加商家后端增加商家前端 删除商家删除商家后端删除商家前端 修改商家修改…...

bat一键批量、有序启动jar

将脚本文件后缀改为 bat&#xff0c;脚本文件和 jar 包放在同一个目录 echo offstart cmd /c "java -jar register.jar " ping 192.0.2.2 -n 1 -w 10000 > nulstart cmd /c "java -jar admin.jar " ping 192.0.2.2 -n 1 -w 30000 > nulstart cmd /c…...

centos7安装mysql数据库详细教程及常见问题解决

mysql数据库详细安装步骤 1.在root身份下输入执行命令&#xff1a; yum -y update 2.检查是否已经安装MySQL&#xff0c;输入以下命令并执行&#xff1a; mysql -v 如出现-bash: mysql: command not found 则说明没有安装mysql 也可以输入rpm -qa | grep -i mysql 查看是否已…...

C++ STL sort函数的底层实现

C STL sort函数的底层实现 sort函数的底层用到的是内省式排序以及插入排序&#xff0c;内省排序首先从快速排序开始&#xff0c;当递归深度超过一定深度&#xff08;深度为排序元素数量的对数值&#xff09;后转为堆排序。 先来回顾一下以上提到的3中排序方法&#xff1a; 快…...

ICP算法和优化问题详细公式推导

1. 介绍 ICP(Iterative Closest Point)&#xff1a;求一组平移和旋转使得两个点云之间重合度尽可能高。 2. 算法流程 找最近邻关联点&#xff0c;求解 R , t R , t R , t R , t R,tR,tR,tR,t R,tR,tR,tR,t&#xff0c;如此反复直到重合程度足够高。 3. 数学描述 X { x 1 ,…...

【安全狗】linux免费服务器防护软件安全狗详细安装教程

在费用有限的基础上&#xff0c;复杂密码云服务器基础防护常见端口替换安全软件&#xff0c;可以防护绝大多数攻击 第一步&#xff1a;下载服务器安全狗Linux版&#xff08;下文以64位版本为例&#xff09; 官方提供了两个下载方式&#xff0c;本文采用的是 方式2 wget安装 方…...

【iOS】自定义字体

文章目录 前言一、下载字体二、添加字体三、检查字体四、使用字体 前言 在设计App的过程中我们常常会想办法去让我们的界面变得美观&#xff0c;使用好看的字体是我们美化界面的一个方法。接下来笔者将会讲解App中添加自定义字体 一、下载字体 我们要使用自定义字体&#x…...

WPF实战学习笔记06-设置待办事项界面

设置待办事项界面 创建待办待办事项集合并初始化 TodoViewModel&#xff1a; using Mytodo.Common.Models; using Prism.Commands; using Prism.Mvvm; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using Sy…...

推荐几个不错的免费配色工具网站

1. Paletton专业的配色套件,提供色轮理论及调色功能。可查看配色预览效果。 网站:http://paletton.com 2. Colormind一个基于机器学习的智能配色工具。可以一键生成配色方案。 网站:http://colormind.io 3. Adobe ColorAdobe官方的配色工具,可以从图片中取色,也可以随机生成配色…...

gitee page发布的静态网站,无法播放目录中的mp4视频

起因是希望在gitee上部署静态网站&#xff0c;利用three.js VideoTexture 环境贴图播放视频。 但是试了多几次 mp4均提示404&#xff0c;资源无法获取&#xff1b; 找了很多方案&#xff0c;最后发现将视频转为ogv 就可以完美适配了&#xff1b; mp4转ogv 附threejs使用ogv进…...

opencv-26 图像几何变换04- 重映射-函数 cv2.remap()

什么是重映射&#xff1f; 重映射&#xff08;Remapping&#xff09;是图像处理中的一种操作&#xff0c;用于将图像中的像素从一个位置映射到另一个位置。重映射可以实现图像的平移、旋转、缩放和透视变换等效果。它是一种基于像素级的图像变换技术&#xff0c;可以通过定义映…...

SkyWalking链路追踪中span全解

基本概念 在SkyWalking链路追踪中&#xff0c;Span&#xff08;跨度&#xff09;是Trace&#xff08;追踪&#xff09;的组成部分之一。Span代表一次调用或操作的单个组件&#xff0c;可以是一个方法调用、一个HTTP请求或者其他类型的操作。 每个Span都包含了一些关键的信息&am…...

【前端知识】React 基础巩固(三十一)——Redux的简介

React 基础巩固(三十一)——Redux 一、Redux是个纯函数 概念 纯函数&#xff08;确定的输入一定产生确定的输出&#xff0c;函数在执行过程中不产生副作用&#xff09;&#xff1a; 在程序设计中&#xff0c;若一个函数符合以下条件&#xff0c;那么这个函数就被称为纯函数…...

拦截Bean使用之前各个时机的Spring组件

拦截Bean使用之前各个时机的Spring组件 之前使用过的BeanPostProcessor就是在Bean实例化之后&#xff0c;注入属性值之前的时机。 Spring Bean的生命周期本次演示的是在Bean实例化之前的时机&#xff0c;使用BeanFactoryPostProcessor进行验证&#xff0c;以及在加载Bean之前进…...

RT thread 之 Nand flash 读写过程分析

文章目录 前言&#xff1a;什么是Nand Flash&#xff1f;1、Nand Flash 读取步骤2、从主存读到Cache2.1 在标准spi接口下读取过程2.2 测试时序&#xff08;SPI频率30MHz&#xff09; 3.从Cache读取数据3.1在标准spi接口读取过程测试时序 前言&#xff1a;什么是Nand Flash&…...

独立站最全出单营销指南,新手卖家赶紧学起来吧!

这是一个需要投入大量时间和精力的挑战&#xff0c;但只有经过筛选在众多品牌和渠道中找到最适合自己的营销策略&#xff0c;才能成功。 新手商家经常会发现自己有很多可以改进的地方&#xff1a;品牌的颜色、字体以及其他一些细节。但真正走向成熟的商家会意识到&#xff0c;…...

Git移除commit过的大文件

前言&#xff1a;在提交推送本地更改至仓库时&#xff0c;误将大文件给提交了&#xff0c;导致push时报错文件过大&#xff0c;因此需要将已经commit的大文件移除后再push 若已知要删除的文件或文件夹路径&#xff0c;则可以从第4步开始 1.对仓库进行gc操作 $ git gc 2.查询…...

再见 Spring Boot 1.X ,Spring Boot 2.X 走向舞台中心

2019年8月6日&#xff0c;Spring 官方在其博客宣布&#xff0c;Spring Boot 1.x 停止维护&#xff0c;Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号&#xff0c;Spring 官方就已经在博客进行过预告&#xff0c;Spring Boot 1.X 将维护到2019年8月1日。 1.5.x 将会…...

Jsonp劫持

JSONP 介绍 jsonp是一种协议&#xff0c;准确的说&#xff0c;他是json的一种使用模式&#xff0c;为了解决Json受同源策略限制的问题。 基本语法 JSONP的基本语法为&#xff1a;callback({“name”:”test”, “msg”:”success”}) 常见的例子包括函数调用&#xff08;如…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...

CSP信奥赛C++常用系统函数汇总

# CSP信奥赛C常用系统函数汇总## 一、输入输出函数### 1. cin / cout&#xff08;<iostream>&#xff09; cpp int x; cin >> x; // 输入 cout << x << endl;// 输出 优化&#xff1a;ios::sync_with_stdio(false); 可提升速度 2. scanf() /…...