iOS ------ UIKit相关
UIView和CALayer
UIView
UIView表示屏幕上的一块矩形区域,它是基本上iOS中所有可视化控件的父类。UIView可以管理矩形区域里的内容,处理矩形区域的事件,包括子视图的管理以及动画的实现。
UIKit相关类的继承关系
UIView继承自UIResponder
,所以UIView可以做事件响应,它也是所有视图(控件)直接或间接的父类
CALayer
CALayer
继承于NSObject
,我们称之为层,CALayer类的概念与UIView非常类似,可以包含图片、文本、背景色等。CALayer直接继承自NSObject,没有事件响应的功能。CALayer中包含API,可判断某点是否在图层范围内,但是没有响应链的存在
UIView和CALayer的关系
在每一个UIView
实例当中,都有一个默认的支持图层layer
,UIView负责创建并且管理这个图层。UIView因为里面有layer层,才具有显示的功能。UIView仅仅是对layer的一层封装,实现了CALayer的delegate,提供了处理事件交互的具体功能,还有动画底层方法的高级API。可以说,CALayer是UIView的内部实现细节。
UIView和CALayer的区别
1,UIView
可以响应事件,CALayer
不可以响应事件
2,一个 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer的 frame
3,UIView
主要对显示的内容的管理而CALayer
主要侧重显示内容的绘制
4,在做 iOS 动画的时候,修改非 RootLayer
的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会。
UIView的CALayer类似于UIView的子view树状结构,也可以向它的layer上添加子layer,来完成某些特殊的表示
UIView *firstView = [[UIView alloc] init];firstView.frame = CGRectMake(200, 200, 200, 200);firstView.backgroundColor = [UIColor redColor];[self.view addSubview:firstView];CALayer *layer = [[CALayer alloc] init];layer.backgroundColor = [[UIColor greenColor] CGColor];layer.position = CGPointMake(100,100); //中心点layer.bounds = CGRectMake(100,100,80,80);[firstView.layer addSublayer:layer];
可以看出并没有在父视图添加新的图层,而是在view上改变了颜色,这和addSubView并不一样。可以看出layer是对View显示内容的绘制。
- CAlayer视图结构类似于UIView的子View树形结构,可以在layer上添加子layer,类似于view添加view来实现一些特殊的表示。不同之处CALayer在添加的时候不会添加新视图,类似于修改原来的layer。
- UIVIew的layer树形在系统内部,被系统维护三份copy
- 第一份,逻辑树,代码可以在里面操作,例如通过代码更改layer的属性(比如frame\bounds)就在这一份进行操作
- 第二份,动画树,这是一个中间层,系统在这一层更改属性,进行各种渲染操作
- 第三份,显示树,这棵树的内容就是当前正被显示在屏幕上的内容
这三棵树的逻辑结构都是一样的,区别只是有各自的属性
UITableView
UITableView代理需要遵循的两个协议以及必须实现的方法
主要是通过2个协议:UITableViewDataSource和UITableViewDelegate
- UITableView需要一个数据源代理(
dataSource
)来显示数据,UITableView会向数据源查询一共有多少行数据以及每一行显示生命数据。没有设置数据源的UITableView只是一个空壳。凡是遵循UITableViewDataSource协议的OC对象,都可以是UITableView的数据源 - 我们也需要为UITableView设置代理对象(
delegate
),以便在UITableView触发某些事件时做出相应的处理。 - 凡是遵循了UITableViewDelegate协议的OC对象,都可以是UITableView的代理对象,一般会让控制器充当充当UITableView的dataSource和delegate,我们可以手动实现协议中的某些方法来完成UITableView的实现。
@protocol UITableViewDataSource的方法
//返回组数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView//返回每组里的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section //cell的实现
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath // section头的title(例如,通讯录不同姓名标识)
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section// section尾段的title
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section// section索引的title集合(例如,通讯录索引,帮助快速找到姓名)
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{}
@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>的方法
//点击cell事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
// 设置cell行高(因为参数是indexPath,所以可以设置不同section的行高,也能设置同一section不容row的行高)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
// section头部的height
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
// section尾部的height
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
// section头部的view
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
// section尾部的view
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
其中代理对象必须实现的方法是DataSource协议的方法
//每组的cell
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//实现cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
几个主要的方法在TableView加载时的执行顺序
- numberOfSectionsInTableView
- numberOfRowsInSection
- cellForRowAtIndexPath
- heightForRowAtIndexPath
TbaleView的cell的复用
在滑动tableView时为了避免cell的重复的销毁创建而消耗性能就出现了cell的复用
简单来说:当创建了多个cell且屏幕显示不了所有的cell,系统会将已经创建不在显示的cell放入复用池中,当需要新建cell并且标识符与复用池中的标识符存在相同的情况,就会调用复用池中的cell,并且使用该cell的所有cell控件
cell的两种复用机制
自定义cell
cell复用会出现的问题
对于不同种类的自定义cell,有时复用会出现问题。如果自定义cell上的控件不同,会出现复用到控件不同的cell,这时就会出现界面的错乱。
解决方法:
- 弃用重用机制 - 从indexpath每次获取新的cell
- 对于不同种类的cell设置不同的标识符,通过不同的标识符去复用相应类型的cell
- 在prepareForReuses中重置所有的subView的显示属性为nil。(当前已经被分配的cell如果被重用了,会调用cell的prepareForReuse通知cell)
tableViewCell的行高计算
动态计算-缓存高度
动态计算
实际开发中,使用最多的应该是动态计算cell高度。例如标题高度不固定,标签不固定,这样就需要更具model里的内容计算行高
使用的时候在tableView的代理设置
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {WMSearchResultQAModel *model = self.dataArray[indexPath.row];return [WMSearchResultQAModel calutWholeCellHeightWithModel:model];
}
这样就可以达到每个cell根据内容展示不同高度的要求了。 这种方法很繁琐,但是也是最精确的,最可控的
缓存行高
当tableView滚动的时会不停的调用heightForAtIndexPath这个代理方法,当cell的高度需要自适应时,就意味着每次回调这个方法都要计算高度,而计算是非常消耗时间的,就会产生卡顿。
为了避免重复且无意义的计算cell高度,缓存高度就释放重要。
缓存高度机制
缓存高度需要一个容器来保存高度数值,可以是model ,一个可变数组,一个可变字典,以达到每当回调 heightForRowAtIndexPath 这个方法时,我们先去这个缓存里去取,如果有,就直接拿出来,如果没有,就计算高度,并且缓存起来。
以model为例
在model里声明个cellheight属性,用于保存Model对应的cell高度,然后在heightForRowAtIndexPath 方法中,如果当前model的cellHeight为0,说明这个cell没有缓存过高度,则计算Cell的高度,并把这个高度记录在model的cellHeight。如果当前model的cellHeight不为0,则直接使用。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {WMSearchResultQAModel *model = self.dataArray[indexPath.row];if (model.cellHeight > 0) {// 有缓存的高度,取出缓存高度return model.cellHeight;}// 没有缓存时,计算高度并缓存起来CGFloat cellHeight; = [WMSearchResultQAModel calutWholeCellHeightWithModel:model];// 缓存给modelmodel.cellHeight = cellHeight;return cellHeight;
}
手动计算高度的两个方法
- sizeToFit
- boundingRectWithSize
sizeToFit
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(10,100, 350, 0)];label.numberOfLines = 0;label.text =@"当前视图的边界和边界大小的变化123123213213213123123123123123213213123213213213123123213";NSLog(@"the label bounds : %@",NSStringFromCGRect(label.frame));[label sizeToFit];NSLog(@"%f",label.frame.size.height);[self.view addSubview:label];
我们不设置高度,设置label.numberOfLines = 0;和[label sizeToFit];可以实现label的最多展开,并可获得相应的高度。
注意事项
- 调整大小:sizeToFit 调整视图的大小,以适应内容。
- 不改变位置:sizeToFit 不会更改视图的位置。
- 确保内容已设置:调用 sizeToFit 之前,应设置好视图的内容。
doundingRectWithSize
返回文本会在所占据的矩形空间
CGRect rect=[(NSString *)obj boundingRectWithSize:CGSizeMake(1000, FONTHEIGHT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil].size.width;
里面的参数如下:
- obj 是指要计算显示的字符串
- boundingRectWithSize 表示计算的宽高限制
- 计算高度时,需要宽度固定:CGSizeMake(1000, CGFLOAT_MAX)
这里的1000也可以用已经确定的控件的宽度替代self.label.width
计算结果表示在宽度最多为1000高度不限时,显示完全字符串需要的高度
计算宽度时,需要高度固定:CGSizeMake(CGFLOAT_MAX, 200)
同理200也可以用已知高度替换:self.label.height
计算结果表示在高度不超过200时,将给定的字符串现实完全需要的宽度 - options是文本绘制的附加选项
- NSStringDrawingUsesLineFragmentOrigin 是默认基线
- attributes字典格式,限定字符串显示的样式,一般限制字体较多,比如:@{NSFontAttributeName:[UIFont systemFontOfSize:16]}
context包括一些信息,例如如何调整字间距以及缩放。最终,该对象包含的信息将用于文本绘制。一般写nil。
UILabel * labelSecond = [[UILabel alloc] init];labelSecond.numberOfLines = 0;labelSecond.text =@"当前视图的边界和边界大小的变化123123213213213123123123123123213213123213213213123123213";labelSecond.font = [UIFont systemFontOfSize:16];//用我们预设的width来算label应该显示的size CGRect rectTest = [labelSecond.text boundingRectWithSize:CGSizeMake(350, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil];//从刚才算的size中取出heigth//加1是怕四舍五入完之后少了一点导致显示的label少了一行CGFloat titleHeight = ceilf(rectTest.size.height) + 1;//用算出来的结果显示labellabelSecond.frame = CGRectMake(10,200, 350, titleHeight);//将label作为子视图添加到父视图[self.view addSubview:labelSecond];
自适应行高-缓存高度
在 iOS8 之后,系统结合autolayout
提供了动态结算行高的方法 UITableViewAutomaticDimension
,做好约束,我们都不用去实现 heightForRowAtIndexPath
这个代理方法了。
实现步骤
1,tableView设置
// 预设行高
self.tableView.estimatedRowHeight = xxx;
// 自动计算行高模式
self.tableView.rowHeight = UITableViewAutomaticDimension;
2,在自定义cell,masonry布局
- (void)layoutSubviews {[super layoutSubviews];[self.headImgView mas_makeConstraints:^(MASConstraintMaker *make) {make.top.left.offset(kSpace15);make.size.mas_equalTo(CGSizeMake(50.f, 50.f));// 在自动计算行高模式下 要加上的 make.bottom.equalTo(self.contentView.mas_bottom).offset(-kSpace15);}];[self.nickNameLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.headImgView.mas_right).offset(12.f);make.top.offset(17.f);}];[self.jobWorkLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.nickNameLabel.mas_right).offset(8.f);make.right.lessThanOrEqualTo(self.contentView.mas_right).offset(-kSpace15);make.top.offset(21.f);}];[self.hospitalLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.headImgView.mas_right).offset(12.f);make.top.equalTo(self.jobWorkLabel.mas_bottom).offset(6.f);}];[self.line mas_makeConstraints:^(MASConstraintMaker *make) {make.left.right.bottom.offset(0);make.height.mas_equalTo(0.5f);}];
}
- 所有子控件都要依赖self.contentView作为约束父控件
- 关键控件要做buttom约束,确定好控件的上下边界,根据控件的动态内容将cell纵向撑开。
3,最关键的一步: [cell layoutIfNeeded]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {WMDoctorEvaluateDescribeInputCell *cell = [tableView dequeueReusableCellWithIdentifier:[WMDoctorEvaluateDescribeInputCell reuseIdentifier] forIndexPath:indexPath];kWeakSelfcell.describeInputBlock = ^(NSString * _Nonnull describeText) {weakSelf.inputDescribeText = describeText;};//关键的一步,解决不正常显示问题[cell layoutIfNeeded];return cell;
}
缓存高度机制
首先获取cell实际显示的高度
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{NSString *key = [NSString stringWithFormat:@"%ld", (long)indexPath.row];[self.heightDict setObject:@(cell.height) forKey:key];NSLOG(@"第%@行的计算的最终高度是%f",key,cell.height);
}
didEndDisplayingCell当cell已经被正真的显示到屏幕上时会调用这个方法,此时的高度是cell的正真高度。根据indexPath.row作为key,将高度缓存进字典。
然后在 heightForRowAtIndexPath 方法里判断,如果字典里有值,则使用缓存高度,否则自动计算:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{NSString *key = [NSString stringWithFormat:@"%ld",indexPath.row];if (self.heightDict[key] != nil) {NSNumber *value = _heightDict[key];return value.floatValue;}return UITableViewAutomaticDimension;
}
ViewController的生命周期
ViewController相关函数以及执行顺序
当一个视图被创建,并且在屏幕上显示的时候
1.alloc 创建对象,分配空间
2. init; 初始化对象,初始化数据
3. loadview 在UIViewController对象的view被访问且为空的时候调用
4. viewDidLoad 控制器载入完成,可以进行自定义数据,以及动态创建其他控件
5. viewWillAppear 视图出现在屏幕之前,马上这个视图就会被展现在屏幕上了
6. viewWillLayoutSubviews 该方法在通知控制器将要布局 view 的子控件时调用
7. viewDidLayoutSubviews 该方法在通知控制器已经布局 view 的子控件时调用
8. viewDidAppear 视图已在屏幕上渲染完成
当一个视图被移除屏幕并且销毁的时候,代码执行的顺序
1,viewWillDisappear 视图将被从屏幕上移除之前执行
2,viewDidDisappear 视图已经被从屏幕上移除,用户看不见这个视图了
3,dealloc 视图被销毁,释放在init和viewDidLoad中创建的对象
离屏渲染
图片渲染和显示的流程
- 在Application阶段,CPU会创建我们的视图,计算视图的一些数据,进行编解码,绘制纹理等操作然后交给GPU
- GPU先通过顶点着色器去确定图像在硬件上的上的具体显示位置,然后通过片源着色器计算每个像素点的颜色值,最后通过光栅化找到像素点的位置,并把颜色显示上去。最终转化为一个个屏幕像素。
- 然后把渲染后的数据放到帧缓存区(FrameBuffer),然后视图控制器就会读取数据交给显示器显示
掉帧
通过屏幕扫描的方式,会通过CRT电子枪从上到下逐行扫描,这个扫描的过程就是读取帧缓存区里的数据,当它扫描完的时候,它就会显示一帧的画面, 当显示完一帧画面后,CRT电子枪又回到原来的位置继续重新扫描显示下一帧。当一个垂直同步信号过来的时候,如果说CPU
和GPU
还没有完成渲染的结果去做提交,也就是没有把数据放到FrameBuffer
里面,这种情况,未过来提交过来这一帧的画面就会被丢弃,然后等待下一次垂直同步信号过来,再来显示新的画面,这个过程被称为掉帧。
离屏渲染
当视图比较复杂的时候,GPU无法扫描视图的全部内容并把渲染数据反在FrameBuffer
中,无法显示画面的全部内容,就需要开辟一块二外的内存缓存区,把剩下的渲染数据放入其中,再合并到FrameBuffer
中,最后进行视图的显示。
导致离屏渲染的操作
- 添加光栅化
- 添加遮罩
- 添加阴影
- 抗锯齿
- 设置背景颜色和圆角
- 不透明
相关文章:

iOS ------ UIKit相关
UIView和CALayer UIView UIView表示屏幕上的一块矩形区域,它是基本上iOS中所有可视化控件的父类。UIView可以管理矩形区域里的内容,处理矩形区域的事件,包括子视图的管理以及动画的实现。 UIKit相关类的继承关系 UIView继承自UIResponde…...

24/8/9算法笔记 随机森林
"极限森林"(Extremely Randomized Trees,简称ERT)是一种集成学习方法,它属于决策树的变体,通常被归类为随机森林(Random Forest)的一种。极限森林的核心思想是在构建决策树时引入极端…...

如何在前后端分离项目中,使用Spring Security
使用 WebSecurityConfigurationAdapter 在前后端分离的架构中,通常使用 Token 进行认证和授权是一种常见的做法。Token 可以是 JSON Web Token(JWT),用于在客户端和服务器之间传递身份信息和访问控制信息。下面我将详细介绍如何在…...

c#怎么折叠代码快捷
在C#中,你可以使用快捷键来折叠或展开代码,以便更好地管理和浏览代码。以下是一些常用的快捷键: 折叠所有方法:使用Ctrl M O。折叠或展开当前方法:使用Ctrl M M。展开所有方法:使用…...

数据库篇--八股文学习第十七天| 什么是慢查询?原因是什么?可以怎么优化?;undo log、redo log、binlog 有什么用?
1、什么是慢查询?原因是什么?可以怎么优化? 答: 数据库查询的执行时间超过指定的超时时间时,就被称为慢查询。 原因: 查询语句比较复杂:查询涉及多个表,包含复杂的连接和子查询&…...

插件、cookie存储,json,ajax详解
1.插件 下载地址:http://github.com/carhartl/jquery-cookie/zipball/v1.4.1 使用文档:jquery-cookie(github.com) 2.存储 初学前端用的是localStorage和sessionStorage,后来又引入了cookie进行存储。 localStorage使用如下 sessionStor…...

快速上手Spring Boot
快速上手Spring Boot (qq.com)...

思路超清晰的 LVS-NAT 模式实验部署
目录 一、实验原理 1、实验基础配置图 2、实验原理 二、实验环境准备 1、准备四台红帽9的主机 2、四台主机的基础配置 (1)client 1)配置主机名:client 2)配置ip:172.25.254.200 (2)lv…...

Android实时通信:WebSocket与WebRTC的应用与优化
文章目录 一、WebSocket在Android中的应用1.1 简介1.2 示例 二、WebRTC在Android中的应用2.1 简介2.2 示例 三、Android实时通信的优化策略3.1 网络优化3.2 延迟降低 四、Android实时通信的安全问题五、实时通信协议的比较六、总结 在现代移动应用中,实时通信已经成…...

力扣刷题之3131.找出与数组相加的整数I
题干描述 给你两个长度相等的数组 nums1 和 nums2。 数组 nums1 中的每个元素都与变量 x 所表示的整数相加。如果 x 为负数,则表现为元素值的减少。 在与 x 相加后,nums1 和 nums2 相等 。当两个数组中包含相同的整数,并且这些整数出现的频…...

非线性表之堆的实际应用和二叉树的遍历
目录 前言:前一篇我已经介绍过了二叉树和堆的介绍和相关代码的实现 一、堆的实现 1.1堆向上调整算法 1.2堆向下调整算法 二、堆的应用 2.1堆的排序 2.2TOP-K问题 三、二叉树的遍历 3.1 二叉树的创建 3.2遍历介绍 3.3前序遍历 3.4中序遍历 3.5后序遍历 …...

os.path库学习之splitext函数
os.path库学习之splitext函数 一、简介 os.path.splitext 是 Python 标准库 os.path 模块中的一个函数,用于将文件名分割成两部分:文件名和扩展名。这个函数非常有用,特别是在处理文件路径和文件扩展名时。 二、语法和参数 语法: os.path…...

Python知识点:如何使用Sqlmap进行SQL注入测试
使用 Sqlmap 进行 SQL 注入测试是一个非常有效的方法,它可以帮助你自动化地检测和利用 SQL 注入漏洞。以下是使用 Sqlmap 进行 SQL 注入测试的详细步骤: 1. 安装 Sqlmap 首先,你需要安装 Sqlmap。Sqlmap 是一个 Python 工具,因此…...

Android Gradle开发与应用 (一) : Gradle基础
Gradle基础 Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的项目自动化构建工具。它使用一种基于 Groovy 的特定领域语言(DSL)来声明项目设置,而不是传统的 XML。Gradle 提供了灵活的构建脚本和强大的依赖管理功能,使其成为…...

Linux驱动开发—设备树分析:GPIO,中断,时钟信息,CPU信息
书接上回:Linux驱动开发—设备树基本概念,语法详解-CSDN博客 文章目录 使用设备树描述中断使用设备树描述CPU节点CPU 节点缓存节点总结 使用设备树描述时钟总结 使用设备树描述GPIO示例设备树节点逐行解析GPIO 单元 使用设备树描述中断 在NXP 官方中截…...

Java全栈解密:从JVM内存管理到Spring框架,揭秘垃圾回收、类加载机制与Web开发精髓的全方位旅程
JVM内存划分 在JVM中,每个线程有自己的虚拟机栈,而整个JVM实例共享一些内存区域。JVM的内存划分主要包括四个部分:程序计数器、虚拟机栈、堆区和方法区(元数据区)。 程序计数器:程序计数器用于存储当前线程…...

【探索Linux】P.46(高级IO —— 五种IO模型简介 | IO重要概念)
阅读导航 引言一、五种IO模型1. 阻塞IO(1)定义(2)特点 2. 非阻塞IO(1)定义(2)特点 3. IO多路复用(1)定义(2)特点 4. 信号驱动IO&#…...

【MongoDB 】MongoDB 介绍及应用,设计到4个案例
MongoDB 介绍概述 基础概念 MongoDB 是非关系型数据库,也就是nosql,存储json数据格式会非常灵活,要比数据库mysql/MariaDB更好,同时也能为mysql/MariaDB分摊一部分的流量压力。 对于经常读写的数据他会存入内存,如此…...

AI浪潮下的程序员生存指南:如何在智能时代锻造不可替代的核心竞争力
人工智能时代,程序员如何保持核心竞争力? 随着AIGC(如chatgpt、midjourney、claude等)大语言模型接二连三的涌现,AI辅助编程工具日益普及,程序员的工作方式正在发生深刻变革。有人担心AI可能取代部分编程工…...

Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC]
文章目录 Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内的相关技术…...

vue 日期控件 100天内的时间禁用不允许选择
vue 日期控件 100天内的时间禁用不允许选择,可以从101天选起 比如,2024年8月9号开始,100天内禁止选择,第101天之后的日期可以选,效果如图所示 // 日期控件代码 加上 :picker-options"pickerOptions" <…...

服务器HTTP响应头安全性优化与漏洞修复方案
在对服务器进行漏洞扫描后,通常会发现一些常见的安全漏洞,特别是涉及HTTP响应头的问题。以下是本次扫描过程中发现的漏洞问题以及对应的修复方案 1.X-Content-Type-Options 响应头缺失 描述: 缺失此响应头可能导致浏览器错误地解析资源类型,存在MIME类型混淆攻击的风险。 …...

4.定时器(TIMER)
理论 预分频寄存器(TIMx_PSC):由于时钟源为:72MHz,T 1/f 1/72MHz,由于不好计算周期时间,则需要分频,若分72则T 1/1MHz 1us(1MHz 一百万秒) 计数方式:向上(递增到某个数触发中断)、向下(递…...

java springboot mqtt控制海康摄像头
GHHKControlService 接口 package org.gh.ghhk.service;public interface GHHKControlService {boolean monitorControl(String payload);}GHHKControlServiceImpl 实现类 package org.gh.ghhk.service.impl;import com.alibaba.fastjson.JSONArray; import com.alibaba.…...

AI大模型02:Prompt Engineering 提示工程
一、什么是提示工程(Prompt Engineering) 1.提示工程,也叫“指令工程” (1)Prompt 就是我们给大模型发送的指令,或者说是在聊天对话框中发送的内容。 Prompt是AGI时代的编程语言。 Prompt是去控制大模型的…...

EasyExcel动态表头导出
1、封装方法 package com.skybird.iot.base.utils;import cn.hutool.core.util.StrUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.w…...

可视化基础的设计四大原则
一个好的数据可视化设计可以帮助观众迅速理解数据背后的意义。然而,如何确保我们的可视化设计既美观又简单易懂呢?本文将介绍四大设计原则——亲密原则、对比原则、对齐原则和重复原则。 1、 亲密原则(Proximity) 定义与应用&am…...

MySQL基础练习题27-上升的温度
目录 题目 准备数据 分析数据 总结 题目 找出与之前(昨天的)日期相比温度更高的所有日期的 id 。 准备数据 ## 创建库 create database db; use db;## 创建表 Create table If Not Exists Weather (id int, recordDate date, temperature int);#…...

只出现一次的数字 II
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 示例 1: 输入:nums [2,2,3,2]…...

第十一章 数据仓库和商务智能 10分
11.1.0语境关系图 11.1 Q 建立数据仓库,有哪些步骤?如何建设?【6 个步骤非常重要!必须知道】 1. 理解需求(P)(目的明确,ETL) (1) 考虑业务目标和业务战略。 (2) 确定业…...