RunLoop UITableViewCell加载高清大图的速度优化

iOS进阶教程2-RUNLOOP优化大图加载 1 为什么要优化大图加载 大图片在渲染的时候,比较耗费时间 我们利用RUNLOOP 来优化: 思路:1.每一次RUNLOOP,都只加载一个小任物,把图片任务放到数组,从数组循环来加载.这样可以是项目达到流畅. 2.只加载当前视图内的图片任务 3.为了不让runloop休眠.我们要用一个timer区持有这个runloop 或者 通知注册runloop事件,让快要睡眠... 阅读详情

RunLoop UITableViewCell加载高清大图的速度优化

2017-02-14 14:25 出处:清屏网 人气:73 评论(0)

iOS开发中,UITableView的优化一直是一个老生常谈的问题,除了常用的预加载,缓存等方法以外,其实利用RunLoop 的循环也可以实现超清大图的流畅加载,具体的使用方法我们利用一个demo来详细理解:

首先,我们有一个需求,就是要从网络加载高清大图到UITableViewCell上,而且每个Cell上面加载多张图片,当cell数量过多的时候,我们需要保持流畅度和加载速度。

那么我们做一个简单的分析:

1,因为这里用到了Runloop循环,那么我们可以监听到runloop的每次循环,
在每一次循环当中我们考虑去进行一次图片下载和布局。
2,既然要在每次循环执行一次任务,
我们可以先把所有图片加载的任务代码块添加到一个数组当中,
每次循环取出第一个任务进行执行。*
3,因为runloop在闲置的时候会自动休眠,
所以我们要想办法让runloop始终处于循环中的状态。

好的,那么我们就可以开始考虑代码实现:

第一步,先把uitableview基本效果实现

@property (strong,nonatomic) UITableView* showImageTableView;
//懒加载
-(UITableView *)showImageTableView{

    if (!_showImageTableView) {
        _showImageTableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
        _showImageTableView.backgroundColor = [UIColor yellowColor];
        _showImageTableView.delegate = self;
        _showImageTableView.dataSource = self;
    }

    return _showImageTableView;
}
//注册
    [self.showImageTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ShowImageTableViewReusableIdentifier];
//添加
    [self.view addSubview:self.showImageTableView];
//数据源代理
#pragma mark- UITableViewDelegate
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:ShowImageTableViewReusableIdentifier];
    //每个cell中添加3张图片
    for (int i = 0; i < 3; i++)
    {
       #这里是添加图片的方法
    }

    return cell;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return 399;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    return 135;
}

第二步,初始化可变数组用来存储任务(代码块)

typedef void(^SaveFuncBlock)();

//存放任务的数组
@property (nonatomic, strong) NSMutableArray *saveTaskMarr;

//最大任务数(超过最大任务数的任务就停止执行)
@property (nonatomic, assign) NSInteger maxTasksNumber;

//任务执行的代码块
@property (nonatomic, copy) SaveFuncBlock saveFuncBlock;


-(NSMutableArray *)saveTaskMarr{

    if (!_saveTaskMarr) {

        _saveTaskMarr = [NSMutableArray array];
    }

    return _saveTaskMarr;
}

    self.maxTasksNumber = 18;

第三步,新建cell添加图片的方法

-(void)addImageToCell:(UITableViewCell*)cell andTag:(NSInteger)tag{

    UIImageView* cellImageView = [[UIImageView alloc]initWithFrame:CGRectMake(tag*(ImageWidth+5), 5, ImageWidth, ImageHeight)];

    dispatch_async(dispatch_get_global_queue(0,0), ^{

        NSData* imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://img5.duitang.com/uploads/item/201312/14/20131214173346_iVKdT.jpeg"]];

        dispatch_async(dispatch_get_main_queue(), ^{

            cellImageView.image = [UIImage imageWithData:imageData];
            [cell.contentView addSubview:cellImageView];
        });
    });
}

第四步,将任务添加到数组保存

//添加任务进数组保存
-(void)addTasks:(SaveFuncBlock)taskBlock{

    [self.saveTaskMarr addObject:taskBlock];
    //超过每次最多执行的任务数就移出当前数组
    if (self.saveTaskMarr.count > self.maxTasksNumber) {

        [self.saveTaskMarr removeObjectAtIndex:0];
    }

}

第五步,在cellForRow方法当中,添加方法:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:ShowImageTableViewReusableIdentifier];

    for (int i = 0; i < 3; i++)
    {
        //添加任务到数组
        __weak typeof(self) weakSelf = self;
        [self addTasks:^{
            //下载图片的任务
            [weakSelf addImageToCell:cell andTag:i];
        }];
    }

    return cell;
}

第六步,监听RunLoop

//注册监听
    [self addRunloopObserver];


//这里面都是C语言 -- 添加一个监听者
-(void)addRunloopObserver{
    //获取当前的RunLoop
    CFRunLoopRef runloop = CFRunLoopGetCurrent();
    //定义一个centext
    CFRunLoopObserverContext context = {
        0,
        ( __bridge void *)(self),
        &CFRetain,
        &CFRelease,
        NULL
    };
    //定义一个观察者
    static CFRunLoopObserverRef defaultModeObsever;
    //创建观察者
    defaultModeObsever = CFRunLoopObserverCreate(NULL,
                                                 kCFRunLoopBeforeWaiting,
                                                 YES,
                                                 NSIntegerMax - 999,
                                                 &Callback,
                                                 &context
                                                 );

    //添加当前RunLoop的观察者
    CFRunLoopAddObserver(runloop, defaultModeObsever, kCFRunLoopDefaultMode);
    //c语言有creat 就需要release
    CFRelease(defaultModeObsever);
}

第七步,也是最关键的步骤,使用定时器,保持RunLoop循环中。

//定时器,保证runloop一直处于循环中
@property (nonatomic, weak) NSTimer *timer;

self.timer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(setRunLoop) userInfo:nil repeats:YES];

//此方法主要是利用计时器事件保持runloop处于循环中,不用做任何处理
-(void)setRunLoop{}

最后一步,在runLoop循环中去处理事件

//MARK: 回调函数
//定义一个回调函数  一次RunLoop来一次
static void Callback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info){
    ViewController * vcSelf = (__bridge ViewController *)(info);

    if (vcSelf.saveTaskMarr.count > 0) {

        //获取一次数组里面的任务并执行
        SaveFuncBlock funcBlock = vcSelf.saveTaskMarr.firstObject;
        funcBlock();
        [vcSelf.saveTaskMarr removeObjectAtIndex:0];
    }
}

好啦。到此为止,我们想要的效果就基本出来了,大家可以去试试:hushed:,同样的道理也可以应用于其他场景。

UITableView的性能优化,提升列表滚动的流畅性 本篇博客目的是:总结UITableView性能优化方向,有些优化方式是我在开发中使用到过的,有些是没有用到过的,当中也有参考、查看很多大神的总结,这才有了本篇博客,仅供大家参考! 阅读详情

相关推荐

RunLoop优化tableView加载大量图片卡顿问题

使用RunLoop优化tableView加载大量图片卡顿问题,可有效解决主线程阻塞问题

RunLoop-UITableViewCell加载高清大图的速度优化

转自:https://www.jianshu.com/p/719cfd7d0a2a iOS开发中,UITableView的优化一直是一个老生常谈的问题,除了常用的预加载,缓存等方法以外,其实利用RunLoop 的循环也可以实现超清大图的流畅加载,具体的使用方法我们利用一个demo来详细理解: 首先,我们有一个需求,就是要从网络加载高清大图到UITableViewCell上,而且每个Cell上面...

小龙的博客 599

UITableView网络图片加载优化 延迟加载

UITableView 中显示网络图片,延迟加载 缓存机制,UITbaleView优化后滚动流畅,并且流量控制到位.体验极好

RunLoop优化加载大量图片的卡顿问题

经典问题:在tableView的cell上加载高清大图,tableView上有很多这样的cell,也就是说 页面展示的时候,要展示大量高清大图。 普通的写法会造成刷新UI耗费大量时间,使主线程阻塞。给用户直观的体验就是页面卡顿 所以这里为了解决这个问题,使用runloop,在runloop进入等待之前的这段空闲时间刷新UI,这样做会使刷新UI的时机稍微向后挪了一点时间,但卡顿问题也不会有

u011604049的博客 6332

Innovus ECO技巧:用setEcoMode+ecoAddRepeater实现批量buffer替换的5个关键步骤

本文详细介绍了在Cadence Innovus工具中,利用setEcoMode与ecoAddRepeater命令实现高效、批量Buffer/Inverter替换的工程化策略。通过启用批处理模式、构建可维护的替换规则、掌握高级定位技巧以及规避布线陷阱等5个关键步骤,帮助芯片设计工程师在ECO阶段大幅提升修改效率与质量,确保设计稳定签核。

d6e7f8的博客 1119

C++ bitset总结

数据结构bitset 术语:某1位置位是置1,某一位复位是某一位清零。 文章目录数据结构bitset一、3种初始化方式二、位访问三、位操作四、 位集操作总结实战练习 一、3种初始化方式 bitset<32> tmp; //默认构造函数,默认全0。 bitset<32> tmp(-1); //从整形数构造 bitset<32> tmp("101"); //从包含1和0的字符串构造 二、位访问 bitset<32> tmp(256)

qq_43807092的博客 721

iOS的GCD、NSThread、NSOperation、锁、Runloop的介绍和使用

GCD GCD (Grand Central Dispatch) GCD两个核心概念:任务和队列 任务 任务就是执行操作的意思,也就是block那段代码。执行操作有两种:同步执行和异步执行。 同步执行(sync):阻塞主线程并执行任务,不会开启新线程任务 异步执行(async):不会阻塞主线程,会开启新线程执行任务,在后台执行 队列 这里的队列就是任务队列,即用来存放任务的队列。队列是一种...

VictorZhang 1734

2026年4月AI爆发周:阿里连推三款模型、字节全双工语音上线,国内大模型进入“落地竞速“新阶段

**摘要:**2026年4月初,国内AI大模型迎来密集发布,阿里、字节、腾讯分别推出新产品。阿里一周发布三款模型,覆盖通用推理、多模态轻量化和长文档处理,API价格大幅下降;字节推出全双工语音模型,实现实时交互,技术难度高;腾讯混元3.0强调工程化和生态整合,面向企业私有化部署。趋势显示,行业从性能竞赛转向落地竞赛,多模态成为主战场,API成本降低,开发者选择更丰富。国内大模型竞争重点转向实际应用和生态整合。

weixin_45526015的博客 1万+

iOS 如何在cell上面毫无卡顿的同时加载大量高清图片

// // ViewController.m // 加载高清大图 // // Created by H on 17/1/12. // Copyright © 2017年 H. All rights reserved. // #import "ViewController.h" //定义一个block typedef BOOL(^RunloopBlock)(void); static

码农--xc 3674

用Python对CAPM和Fama French Three Factor model的初步学习

用Python对CAPM和Fama French Three Factor model的初步学习概述介绍建模与分析CAPMFama French Three-Factor Model总结 概述 本文主要使用CAPM(资本资产定价模型)和Fama French Three Factor model来评估中国股票市场的股票价格。 使用CAPM来选择投资组合,然后建立Fama法国三因素模型来评估投资组合...

weixin_43168138的博客 5461

3.38 工业缺陷检测实战:物体表面缺陷检测,从图像处理到深度学习

本文介绍了工业缺陷检测的完整流程,从传统图像处理到深度学习方法。首先定义了缺陷检测任务的目标和应用场景,然后详细讲解了传统图像处理方法(边缘检测、阈值分割等)和深度学习方法(分类、检测、分割模型)。文章最后总结了核心要点,提出了思考题和实践建议,建议从简单方法开始逐步优化。下一篇将介绍工业视觉基础技术——相机标定与角点检测。

yonggeit的博客 2887

Runloop与UITableView简单结合

Runloop性质 概述 当程序执行时,默认线程执行完任务就退出了,如果我们想线程持续地处理事件,则需要为线程添加循环机制Runloop,Runloop是事件分发和实现的机制; Runloop是一个对象,这个对象处理线程持续执行程序运行中出现的各种事件(比如说触摸事件、UI刷新事件、定时器事件、Selector事件),从而使程序持续运行。在没有需要处理事件时休息,在有事件到来是唤醒处理,节省C...

jbr5740的专栏 449

【STM32项目】基于STM32设计的震动马达超声波电机高频震动——高级定时器PWM互补输出带死区控制__资料编号3

实现高级定时器互补输出带死区控制,实现震动/超声波电机/马达,高频震动。使用 STM32F103 芯片输出两路互补 PWM,并带有死区和刹车控制功能。定时器 1 通道 1 及其互补通道输出PWM,且带死区控。当定时器 1 的刹车输入引脚被拉高时,产生刹车时间,即定时器 8 停止输出 PWM。当刹车输入引脚被拉高时,通道 1 和通道 2 将从有波形输入状态转换成无效电平状态。

嵌入式阿齐Archie 6742

RUNLOOP优化大图加载

转自:https://blog.youkuaiyun.com/bruceyou1990/article/details/80199650  1 为什么要优化大图加载 大图片在渲染的时候,比较耗费时间  我们利用RUNLOOP 来优化: 思路:1.每一次RUNLOOP,都只加载一个小任物,把图片任务放到数组,从数组循环来加载.这样可以是项目达到流畅.  2.只加载当前视图内的图片任务  3.为了不让run...

小龙的博客 2662

使用菱FX5U系列PLC实现以太网通信的具体方法示例

接下来,我们将创建一个简单的CPU通信功能,以实现与其他设备的以太网通信。在上述代码中,我们首先设置访问号,然后创建一个数据读取命令(M_READ)和一个数据写入命令(M_WRITE)。此外,在实际应用中,您还需要确保PLC和其他设备之间的网络连接正常,并且遵循相应的通信协议。在上述代码中,我们执行了数据读取命令,并将接收到的响应存储在M_RESPONSE变量中。通过简单CPU通信功能,菱FX5U系列PLC可以实现与其他设备的以太网通信。我们将提供相应的源代码和详细的说明,以帮助您轻松实现这一功能。

DevCyberX的博客 1527

C#【通用方法】字节数组添加、移除、获取的方法类(妙用List<byte>,开发中常用)

C#【通用方法】添加移除字节的方法类(妙用List,开发中常用)

星Yeah 的博客 3360

利用RunLoop优化tableView

原文链接:http://www.qingpingshan.com/rjbc/ios/214222.html iOS开发中,UITableView的优化一直是一个老生常谈的问题,除了常用的预加载,缓存等方法以外,其实利用RunLoop 的循环也可以实现超清大图的流畅加载,具体的使用方法我们利用一个demo来详细理解: 首先,我们有一个需求,就是要从网络加载高清大图到UITableViewCe

Jamison Fan的博客 4486

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

ios-RunLoop使tableView流畅化

当我们如果想要在cell中显示很多高清的大图片的时候如果一下子加载很多,肯定会有卡顿现象的产生,是一个耗时操作,我们可能会想着耗时操作的话就往子线程中扔,但是我们是在做UI的操作,所以我们不应该放到子线程中。这样的话我们应该考虑用Runloop,每次循环我们再去加载一张图片,这样的话卡顿结果就会解决,因为相比较一次循环加载多张图片肯定好很多。 首先我们应该去监听Runloop的状态,因为只有这样

rv0p111 861

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Lazy懒加载(延迟加载)UITableView

举个例子,当我们在用网易新闻App时,看着那么多的新闻,并不是所有的都是我们感兴趣的,有的时候我们只是很快的滑过,想要快速的略过不喜欢的内容,但是只要滑动经过了,图片就开始加载了,这样用户体验就不太好,而且浪费内存.              这个时候,我们就可以利用lazy加载技术,当界面滑动或者滑动减速的时候,都不进行图片加载,只有当用户不再滑动并且减速效果停止的时候,才进行加载.

SMY_API的专栏 1284

CFRunloop 优化TableView加载高清大图UI卡顿问题。单独分批加载

TableView卡顿环境分析:        tableView加载过多的高清大图,Runloop不只处理iOS事件,渲染图形也是runloop处理的。       而渲染图形的UI操作必须在主线程中,不能开辟线程进行图形处理。       在拖动tableView的时候,Runloop要处理拖动事件,还要处理过多图片渲染,而造成卡顿。 解决卡顿分析:       1、Runl

星宇大前端 5008

tableview预加载

原理: tableview的调用 -(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath方法 判断indexPath.row和服务器每页返回的数据的count值大小进行比较(例子中是每页返回20条数据),进行加载数据,实现提前预先加载服务器...

weixin_34274029的博客 594

UITableView加载网络图片 cell适应图片高度

UITableView加载网络图片 cell适应图片高度一、自定义cell.xib上拖拽一个imageView二、在VC.m 中根据图片尺寸设置cell高度⚠️⚠️⚠️注意:不要在cell的setModel里设置图片,因为首次加载图片时会调用[self.tableView reloadData],导致死循环。 一、自定义cell.xib上拖拽一个imageView 上下左右贴边约束,连线属性 cell.h @property (strong, nonatomic) IBOutlet UIImageView

biyuhuaping的专栏 1794

iOS开发使用tableView从服务器加载图片时的卡顿现象解决方案

新手做开发的时候一般都会遇到

王绵杰的个人博客 1809

RunLoop对tableView的性能优化

tableView中的cell是每次出现在屏幕上的时候加载他的内容。so,在加载cell的时候尽量不要做耗时操作,不然在tableView滚动的时候出现卡顿或卡死的情况。 有一种耗时操作是在别的情况下无法解决的。加载较大图片,图片越大,加载越慢,如果一个cell上有多张图片,那么会更加卡顿。这个时候就可以用RunLoop去处理。 tableView重用cell时,是在一次RunLoop循环中处...

u011279386的博客 1243

RunLoop总结:RunLoop的应用场景(三)

今天要讲的RunLoop的应用场景可能太简单了,所以东西比较少。因为跟UITableView、UICollectionView等的滑动优化有关,就顺便总结一下会影响UITableView、UICollectionView等视图滑动流畅的因素。 参考资料 好的书籍都是值得反复看的,那好的文章,好的资料也值得我们反复看。我们在不同的阶段来相同的文章或资料或书籍都能有不同的收...

weixin_30437481的博客 826
上一篇: swift3.0 - 闭包(block)
下一篇: Runtime--将信息对象归档解档
董其林
博客等级 码龄11年 1粉丝 21原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值