// 提前计算并缓存好高度
// 滑动时按需加载, 防止卡顿 配合SDWebImage
https://github.com/johnil/VVeboTableViewDemo
dispatch_async
(
DISPATCH_QUEUE_PRIORITY_DEFAULT
, ^{
// 异步绘制
});
// 缓存一切可以缓存的
// 默认高度44 定高的cell最好指定高度, 减少不必要的计算
self
.
tabelView
.
rowHeight
=
88
;
// 减少视图数目
// 减少多余的绘制操作
// 不给cell动态添加subView 用hidden属性 控制显示/隐藏
// 网络请求, 图片加载 开启多线程
// willDisplayCell 可以将数据绑定放在cell显示出来之后再执行 以提高效率
// 缓存不便于重用的view (存model里)
// -------- 自适应高度 --------
// 尽量提高计算效率, 已计算过的高度需要进行缓存, 没必要进行第二次运算
// 必须满足3个条件
// 1. cell.contentView 四边与内部元素有约束关系(Autolayout)
// 2. 指定estimatedRowHeight属性的默认值
self
.
tabelView
.
estimatedRowHeight
=
44
;
// 3. 指定rowHeight属性为 automatic dimension
self
.
tabelView
.
rowHeight
=
UITableViewAutomaticDimension
;
// -------- 离屏渲染: 圆角/阴影 --------
// 离屏渲染: 圆角/阴影, 另外开辟渲染缓冲区, 消耗性能 (多: 缓冲区频繁合并 上下文频繁切换, 导致掉帧)
UIImageView
*imgV = [[
UIImageView
alloc
]
initWithImage
:[
UIImage
imageNamed
:
@"placeholder"
]];
imgV.
frame
=
CGRectMake
(
100
,
100
,
100
,
100
);
[
self
.
view
addSubview
:imgV];
// 优化方案1: (推荐使用) CAShapeLayer UIBezierPath 结合, 可设置单个圆角
UIBezierPath
*maskPath = [
UIBezierPath
bezierPathWithRoundedRect
:imgV.
bounds
byRoundingCorners
:
UIRectCornerAllCorners
cornerRadii
:imgV.
bounds
.
size
];
CAShapeLayer
*maskLayer = [[
CAShapeLayer
alloc
]
init
];
// 设置大小
maskLayer.
frame
= imgV.
bounds
;
// 设置图形样子
maskLayer.
path
= maskPath.
CGPath
;
imgV.
layer
.
mask
= maskLayer;
// 说明: AShapeLayer动画渲染直接提交到手机的GPU当中,相较于view的drawRect方法使用CPU渲染而言,其效率极高,能大大优化内存使用情况
// 优化方案2: 使用贝塞尔曲线UIBezierPath Core Graphics框架画出一个圆角
// 开始对imageView进行画图
UIGraphicsBeginImageContextWithOptions
(imgV.
bounds
.
size
,
NO
,
1.0
);
// 使用 贝赛尔曲线 画出一个圆形图
[[
UIBezierPath
bezierPathWithRoundedRect
:imgV.
bounds
cornerRadius
:imgV.
frame
.
size
.
width
]
addClip
];
[imgV
drawRect
:imgV.
bounds
];
imgV.
image
=
UIGraphicsGetImageFromCurrentImageContext
();
// 结束画图
UIGraphicsEndImageContext
();
// shadow shadowPath优化
imgV.
layer
.
shadowColor
= [
UIColor
redColor
].
CGColor
;
imgV.
layer
.
shadowOpacity
=
0.8
;
imgV.
layer
.
shadowRadius
=
2.0
;
imgV.
layer
.
shadowOffset
=
CGSizeMake
(
0
,
0
);
CGFloat
width =
3
;
CGRect
imgFrame = imgV.
bounds
;
CGRect
shadowFrame =
CGRectMake
(imgFrame.
origin
.
x
- width, imgFrame.
origin
.
y
- width, imgFrame.
size
.
width
+
2
*width, imgFrame.
size
.
height
+
2
*width);
UIBezierPath
*path = [
UIBezierPath
bezierPathWithRect
:shadowFrame];
imgV.
layer
.
shadowPath
= path.
CGPath
;
// 使用异步进行layer渲染(Facebook开源的异步绘制框架AsyncDisplayKit)
// 设置layer的opaque(不透明)值为YES,减少复杂图层合成
// 尽量使用不包含透明(alpha)通道的图片资源
// 尽量设置layer的大小值为整形值
// -------- Core Animation工具检测离屏渲染 --------
// Xcode->Open Develeper Tools->Instruments
// 可以将数据绑定放在cell显示出来之后再执行 以提高效率
- (
void
)tableView:(
UITableView
*)tableView willDisplayCell:(
UITableViewCell
*)cell forRowAtIndexPath:(
NSIndexPath
*)indexPath {
}
- (
UITableViewCell
*)tableView:(
UITableView
*)tableView cellForRowAtIndexPath:(
NSIndexPath
*)indexPath {
static
NSString
*cellIncdentify =
@"Cell"
;
UITableViewCell
*cell = [tableView
dequeueReusableCellWithIdentifier
:cellIncdentify];
if
(!cell) {
cell = [[
UITableViewCell
alloc
]
initWithStyle
:
UITableViewCellStyleDefault
reuseIdentifier
:cellIncdentify];
}
// tableView停止滑动的时候异步加载图片
if
(tableView.
dragging
==
NO
&& tableView.
decelerating
==
NO
) {
// 开始异步加载图片
NSArray
*visiblePaths = [tableView
indexPathsForVisibleRows
];
for
(
NSIndexPath
*
i
ndexPath
in
visiblePaths) {
// 获取dataSource里的对象, 并且判断加载完成是不需要再次异步加载
}
}
return
cell;
}