龙空技术网

ios UITableView实现图片懒加载

洲游历累 165

前言:

现时兄弟们对“js 动态添加img在ios不显示”可能比较讲究,小伙伴们都需要剖析一些“js 动态添加img在ios不显示”的相关内容。那么小编同时在网络上网罗了一些有关“js 动态添加img在ios不显示””的相关文章,希望同学们能喜欢,姐妹们快快来学习一下吧!

开发中常用到UITableView加载大量数据,需要性能优化问题,本文通过UITableView加载大量图片案例来说明。

实现方式一:基于可见cell视图加载图片

实现原理: tableView加载可见的cell图片(手指未拖动和减速动画快结束才加载)

(1)绑定cell时,判断手指未拖动和减速动画快结束,才加载图片

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellId"];    if (cell==nil) {        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellId"];    }    ImageRecord *record = self.dataList[indexPath.row];    if (record.image) {       cell.imageView.image = record.image;    }else{        cell.imageView.image = [UIImage imageNamed:@"head"];        //手指未拖动和减速动画快结束        if (!tableView.dragging && !tableView.decelerating) {            //加载图片            [self downloadImage:indexPath];        }    }    cell.textLabel.text = record.title;    return cell;}

(2)tableview停止滚动,开始加载图像,实现以下代理方法

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {  //加载可见cell图片  [self showVisibleCellImage];}

(3)tableView停止拖拽,没有减速动画,实现以下代理方法

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {  //加载可见cell图片  if (!decelerate) {      [self showVisibleCellImage];  }}

(4)退出界面时,取消任务下载

- (void)viewDidDisappear:(BOOL)animated{    [super viewDidDisappear:animated];    //取消下载图片任务    NSArray *values = self.tasksDic.allValues;    [values makeObjectsPerformSelector:@selector(cancel)];}

2.实现方式二:基于runloop实现图片渲染

原理:创建定时器,获取当前线程runloop ,并监听runloop将进入休眠事件,处理图片加载,runloop每次循环时,只加载一次图片渲染。

(1)创建定时器

// 让runloop一直转起来 self.timer = [NSTimer scheduledTimerWithTimeInterval:0.0001 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
- (void)timerMethod {    // 添加timer才开启block任务的执行,不然数组tasks会因为添加30个而导致数组中保存的仅仅是最后五个,TableView一出来cell图片没显示,因为就没有对应的任务       self.display = YES;}

(2)通过当前定时器的线程的runloop, 监听runloop将进入休眠事件

 // 创建观察者   // 拿到当前的runloop   CFRunLoopRef runloop = CFRunLoopGetCurrent();   // 定义一个上下文   CFRunLoopObserverContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};   // 创建一个观察者   _defaulModeObserver  = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeWaiting, YES, 0, &Callback, &context);   CFRunLoopAddObserver(runloop, _defaulModeObserver, kCFRunLoopCommonModes);   CFRelease(runloop);
static void Callback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {    SecondViewController *vc = (__bridge SecondViewController *)info;    //无任务  退出    if (vc.tasks.count == 0) {        return;    }    if (vc.display) {        //从数组中取出任务        RunloopBlock task = vc.tasks.firstObject;        if (task) {            task();            //执行完任务之后移除任务            [vc.tasks removeObjectAtIndex:0];        }    }    }

(3)绑定cell时,添加加载图片任务

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    ImageCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierID forIndexPath:indexPath];    NSInteger row = indexPath.row;    cell.imageView1.image = nil;    cell.imageView2.image = nil;    cell.imageView3.image = nil;        //添加任务1    [self addTask:^{        dispatch_async(dispatch_get_global_queue(0, 0), ^{             UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",(long)(row%3)]];             dispatch_async(dispatch_get_main_queue(), ^{                cell.imageView1.image = img;            });        });    }];    //添加任务2    [self addTask:^{        dispatch_async(dispatch_get_global_queue(0, 0), ^{             UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",(long)(row%3)]];             dispatch_async(dispatch_get_main_queue(), ^{                cell.imageView2.image = img;            });        });    }];    //添加任务3    [self addTask:^{        dispatch_async(dispatch_get_global_queue(0, 0), ^{             UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",(long)(row%3)]];             dispatch_async(dispatch_get_main_queue(), ^{                cell.imageView3.image = img;            });        });    }];        return cell;}

添加任务方法:

- (void)addTask:(RunloopBlock)task {    if (self.display) {        // 判断当前待执行的代码块是否超出最大代码块数        if (self.tasks.count > self.maxQueueLength) {            // 干掉最开始的代码块            [self.tasks removeObjectAtIndex:0];        }    }    // 将代码块添加到可变数组中    [self.tasks addObject:task];}

3.懒加载图片demo源代码下载

下载地址:

标签: #js 动态添加img在ios不显示