需要脚本演示、定制部署或海外获客方案?访问 Facebook18 官网
首页 / twitter引流推广

facebook很卡(为什么facebook会闪退)

2023-01-11twitter引流推广静态 HTML 文章

关于facebook很卡(为什么facebo,资料不少但靠谱的不多。本文按真实操作顺序整理,看完就能照着做。

如何提升自己的技术水平,多研究蕞新技术解决方案;平时忙项目,每天多晚都要温习技术总结;面试必须要面对,区别高手和普通码农的区别。废话少说,上代码

1、Cell 的重用

#示例1:常见用法

- tableView:tableViewcellForRowAtIndexPath:indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if { cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } return cell;}

[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 就是 cell 重用的标志性语句。上面的代码逻辑是:当需要显示一个 Cell 时,系统会先去重用队列中查询是否有可重用的 cell,如果有则复用它,如果没有则新建一个 cell。

#示例2:读取 UITableView 的属性

+ ivarList{ unsigned int count = 0; Ivar *ivars = class_copyIvarList; for { Ivar ivar = ivars[i]; const char *charName = ivar_getName; const char *charType = ivar_getTypeEncoding; NSLog; } free;}

上面通过运行时函数 class_copyIvarList 来读取 UITableView 中所有成员变量。结果如下:

。。。Name:_visibleCells,Type:@"NSMutableArray"Name:_reusableTableCells,Type:@"NSMutableDictionary"。。。

从打印结果可以看到,UITableView 中包括了以下两个属性:

visibleCells:reusableTableCells:

Cell的重用逻辑:

.假如当前屏幕能显示10个 Cell,在 UITableView 开始渲染时,系统会通过 -initWithStyle:reuseIdentifier: 方法创建10个新的 cell 并显示,这些 cell 会被放入 visibleCells 这个数组中。

.向下滑动 TableView,当 cell1 完全移出屏幕,并且 cell22 完全显示出来时,cell22 会被加入到 visiableCells,而 cell1 则被移出 visiableCells 并加入到 reusableTableCells 中。

.接着向下滑动 TableView,因为 cell1 已经在 reusableTableCells 中,所以 即将显示的弟12个 cell 会重用 cell1。因此 cell1 会被移出 reusableTableCells 并加入到 visiableCells中;同时 cell2 移出 visiableCells 并加入到 reusableTableCells 中。

.接下来的重用以此类推。。

注意: cell 是重用的,所以在配置 cell 时一定要重新设置重用的 cell,不要遗留老的数据。

2、卡顿与离屏渲染

tableview 使用中常会出现性能问题,其中会涉及到离屏渲染

2.1 卡顿的原因

通常来说,计算机系统中 CPU、GPU、显示器是协同工作的:CPU 负责计算显示的内容,如视图的创建、布局计算、图片解码、文本绘制等,完成后提交到 GPU;GPU 负责对 CPU 提交的内容进行变换、合成、渲染,完成后将渲染结果放入帧缓冲区;视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示。

如果在一个 VSync 时间内,CPU 或者 GPU 没有完成内容提交,则那一帧就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。这就是界面卡顿的原因。

2.2.离屏渲染

#离屏渲染: 指的是GPU在当前屏幕缓冲区以外开辟一个缓冲区进行渲染操作;

#当前屏幕渲染: 是指GPU的渲染操作是在当前用于显示的屏幕缓冲区进行。

离屏渲染对性能影响很大,主要是因为离屏渲染会创建新的缓冲区,且在离屏渲染的整个过程,需要多次切换上下文环境。这些操作的开肖很大,尤其是当有大量离屏渲染的情况时。

#为什么会有离屏渲染机制?:

有些效果被认为不能直接呈现于屏幕,而需要在别的地方做额外的处理预合成。图层属性的混合体没有预合成之前不能直接在屏幕中绘制,所以就需要屏幕外渲染。屏幕外渲染并不意味着软件绘制,但是它意味着图层必须在被显示之前在一个屏幕外上下文中被渲染。

#会触发离屏渲染的场景:

为图层设置遮罩;将图层的 layer.masksToBounds 或 view.clipsToBounds 设置为YES;将图层 layer.allowsGroupOpacity 设置为YES 且 layer.opacity小于1.0;为图层设置阴影;为图层开启光栅化:layer.shouldRasterize = YES;为图层设置圆角 layer.cornerRadius;为图层设置抗锯齿性:layer.allowsEdgeAntialiasing = YES;文本;使用 CGContext 在 drawRect :方法中绘制大部分情况下会导致离屏渲染。

#优化方案:

使用 CAShapeLayer 配合 UIBezierPath 画圆角;使用 ShadowPath 指定 layer 的阴影效果路径;设置 layer.opaque = YES,减少复杂图层合成;尽量使用不包含透明通道的图片资源;尽量设置 layer 的大小值为整形值。使用异步进行 layer 渲染;离屏渲染的触发方式

设置了以下属性时,都会触发离屏绘制:

shouldRasterizemasksshadowsedge antialiasinggroup opacity复杂形状设置圆角等渐变

其中shouldRasterize是比较特别的一种:

光栅化的概念:将图转化为一个个栅格组成的图像。
光栅化的特点:每一个元素对应帧缓冲区中的一个像素。

光栅化有什么好处?

shouldRasterize = YES 在其他属性触发离屏渲染的同时,会将光栅化后的内容缓存起来,如果对应的layer及其sublayers没有发生改变,在下一帧的时候可以直接复用。shouldRasterize = YES,这将隐式的创建一个位图,各种阴影遮罩等效果也会保存到这个位图中并缓存起来,从而减少渲染的频度。

举个例子

如果在滚动tableview时,每次都执行圆角设置,肯定会阻塞UI,设置这个将会使滑动更加流畅。当shouldRasterize设置成true时,layer被渲染成一个bitmap,并缓存起来,等下次使用时不会再重新去渲染了。实现圆角本身就是在做颜色混合,如果每次页面出来时都blending,消耗太大,这时shouldRasterize = yes, 下次就只是简单的从渲染引擎的cache里读取那张bitmap,节约系统资源。

而光栅化会导致离屏渲染,影响图像性能,那么光栅化是否有助于优化性能,就取决于光栅化创建的位图缓存是否被有效复用,而减少渲染的频度。可以使用Instruments进行检测

1当你使用光栅化时,你可以开启“Color Hits Green and Misses Red”来检查该场景下光栅化操作是否是一个好的选择。如果光栅化的图层是绿色,就表示这些缓存被复用;如果是红色,就表示缓存会被重复创建,这就表示该处存在性能问题了。

注意:

对于经常变动的内容,这个时候不要开启,否则会造成性能的浪费。

#2020生计大会# #面试iOS#头条热搜#

鸣谢:路漫漫其修远兮Wzt 、听麻雀的话、brhave

查看演示与获取方案

读完本篇后,可通过下方入口查看演示视频、联系客服或访问主站。