CFRunloop 优化TableView加载高清大图UI卡顿问题。单独分批加载
来源:互联网 发布:嘉嘉购物业软件 编辑:程序博客网 时间:2024/04/28 04:57
TableView卡顿环境分析:
tableView加载过多的高清大图,Runloop不只处理iOS事件,渲染图形也是runloop处理的。
而渲染图形的UI操作必须在主线程中,不能开辟线程进行图形处理。
在拖动tableView的时候,Runloop要处理拖动事件,还要处理过多图片渲染,而造成卡顿。
解决卡顿分析:
1、Runloop在一次循环渲染图片过多,那就让Runloop一次处理一张图片
2、将处理图片的代码放在block中,然后加入数组中,处理几次加入几次。
3、我们只需要渲染,tableView显示的图片,显示图片有最大个数。移开屏幕或者不处理的从队列数组里删去。
2和3其实就是逻辑的问题,不赘述了,下面会给出demo源码。主要讲讲第一个问题,是处理卡顿的重点。
第一个问题实现代码如下:
#pragma mark 设置runloop监听
//这里面都是C语言 --添加一个监听者
-(void)addRunloopObserver{
//获取当前runloop
CFRunLoopRef currentRunloop = CFRunLoopGetCurrent();
//runloop观察者上下文,为下面创建观察者准备,只有创建上下文才能在回调了拿到self对象,才能进行我们的逻辑操作.这是一个结构体。
/**
typedef struct {
CFIndex version;
void * info;
const void *(*retain)(const void *info);
void (*release)(const void *info);
CFStringRef (*copyDescription)(const void *info);
} CFRunLoopObserverContext;
**/
CFRunLoopObserverContext context = {
0,
(__bridgevoid *)(self),
&CFRetain,
&CFRelease,
NULL
};
//创建Runloop观察者 kCFRunLoopBeforeWaiting 观察在等待状态之前 runloop有下面几种状态看英文应该知道了。
/*
kCFRunLoopEntry = (1UL << 0),
kCFRunLoopBeforeTimers = (1UL << 1),
kCFRunLoopBeforeSources = (1UL << 2),
kCFRunLoopBeforeWaiting = (1UL << 5),
kCFRunLoopAfterWaiting = (1UL << 6),
kCFRunLoopExit = (1UL << 7),
kCFRunLoopAllActivities = 0x0FFFFFFFU
*/
staticCFRunLoopObserverRef obserberRef;
obserberRef =CFRunLoopObserverCreate(NULL,kCFRunLoopBeforeWaiting,YES, 0,&callback, &context);
//给当前runloop添加观察者
CFRunLoopAddObserver(currentRunloop, obserberRef,kCFRunLoopDefaultMode);
//释放观察者
CFRelease(obserberRef);
}
//观察回调
static void callback(CFRunLoopObserverRef observer,CFRunLoopActivity activity,void *info){
ViewController * vcSelf = (__bridgeViewController *)(info);
if (vcSelf.TaskMarr.count >0) {
//获取一次数组里面的任务并执行
runloopTask task = vcSelf.TaskMarr.firstObject;
task();
[vcSelf.TaskMarrremoveObjectAtIndex:0];
}else{
return;
}
}
- 先推理下,如果我要把任务放到Runloop里操作,首先我要获取Runloop。
- 然后我们需要一个观察者,找一个时机把任务放进去。如果对runloop了解的话,会想到CFRunLoopObserver.然后我们创建一下这个观察者对象。
- 然后把观察者扔进runloop,这样我们就能拿到,Runloop等待之前的回调。
- 然后把任务扔到回调中。
方案如下:
//给runloop一个事件源,让Runloop不断的运行执行代码块任务。
[NSTimerscheduledTimerWithTimeInterval:0.1target:selfselector:@selector(runloopalive)userInfo:nilrepeats:YES];
//如果方法里什么都不干,APP性能影响并不大。但cpu增加负担,
-(void)runloopalive{
//什么都不干
}
demo地址:https://github.com/RainManGO/tableView-Caton-optimization
- CFRunloop 优化TableView加载高清大图UI卡顿问题。单独分批加载
- Android 加载高清大图
- tableview 加载图片卡顿问题
- RunLoop UITableViewCell加载高清大图的速度优化
- Android_性能优化ViewPager加载高清大图oom解决方案
- 通过webView全屏加载高清大图片,解决不能全屏高清加载图片问题
- AsyncLoadLocalImage ios 加载本地高清大图
- Android RecyclerView加载时大图卡顿
- Android_性能优化之ViewPager加载成百上千高清大图oom解决方案
- Android_性能优化之ViewPager加载成百上千高清大图oom解决方案
- GCD优化Tableview列表大图卡顿实用方法
- Android之打造自己加载高清大图及瀑布流框架.解决错位等问题.
- 使用SDWebimage加载高清大图遇到内存警告的问题
- UIImageView 加载高清大图时内存管理
- 一招解决Android 加载高清大图
- 多个ImageView 加载高清大图的内存管理
- Android 高清加载长图或大图方案
- Android中加载高清大图及图片压缩方式
- 修改eclipse文件的编码格式
- Python-杂记
- 统计以a开头的词
- 学习9:rosed命令的简单介绍 + 创建ROS消息和ROS服务。
- xgboost详解
- CFRunloop 优化TableView加载高清大图UI卡顿问题。单独分批加载
- 第一个Ajax,判断用户名是否可用
- 并发服务器中的fork函数、 子进程与父进程的区别
- webrtc VCMQmResolution分辨率调整模块简略分析
- Android DrawerLayout实现侧拉菜单
- 管道
- 单例模式
- Linux 帮助命令(man/help/info)
- MongoDB数据库查询方法