多线程学习---解析苹果官网代码《LazyTableImages》
2016-03-27 21:33
387 查看
很早以前就看过《LazyTableImages》的代码,当时只是大致看了一下它的原理,没有很详细的研读。最近在看第三方开源框架的代码,学习优化策略以及优雅的代码风格,提高自身水平,希望与大家一起学习和共同讨论。
一、简要流程说明。
1、通过RSS feed建立URL请求获取XML数据;
2、通过获取的XML数据,创建ParseOperation在后台使用NSXMLParser运行解析XML数据得到想要的数据存放在NSArray里面;
3、ParseOperation执行完后告诉table view在主线程上面重新加载数据;
4、当UITableViewCell不再滚动或拖动的时候,通过可见cells的indexPath在NSArray里面得到cells对应的每一个imageURLString,为每一个imageURLString创建一个IconDownloader下载图片,每一个IconDownloader下载完毕通过委托的方式为cell更新image。
二、详细流程讲解:
1.利用NSOperation队列异步解析RSS,ParseOperation执行完成,通知主线程重新加载数据,更新UI,主要代码如下:
NSOperation的相关知识可以查看http://blog.csdn.net/jasonjwl/article/details/50992720
1.1 ParseOperation开始解析,会调用文件ParseOperation.m中的main方法,将解析后的结果存储在appRecordList数组
= weakParser.appRecordList;通过Block回调通知rootViewController.tableView进行更新。
2.1 在加载cell的时候,做了相应优化 ,如下所示:
当等待cell加载的时候,添加占位cell
当没有缓存images,只有等滚动停止的时候才会让下载器下载图片
如果cell的image正在下载,则返回占位图片
思考:1.如果图片为圆角图片,该如何优化?
2.除了上述提了的一些优化cell方法,还有那些优化cell的方法。
欢迎大家交流讨论!如有不对的地方,请指出,谢谢!本人正在找iOS方面的工作,如有合适的职位请跟我联系,谢谢!
后续我将带来MJExtension和SDWebImage源码解析系列
LazyTableImages的下载地址:https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html
一、简要流程说明。
1、通过RSS feed建立URL请求获取XML数据;
2、通过获取的XML数据,创建ParseOperation在后台使用NSXMLParser运行解析XML数据得到想要的数据存放在NSArray里面;
3、ParseOperation执行完后告诉table view在主线程上面重新加载数据;
4、当UITableViewCell不再滚动或拖动的时候,通过可见cells的indexPath在NSArray里面得到cells对应的每一个imageURLString,为每一个imageURLString创建一个IconDownloader下载图片,每一个IconDownloader下载完毕通过委托的方式为cell更新image。
二、详细流程讲解:
1.利用NSOperation队列异步解析RSS,ParseOperation执行完成,通知主线程重新加载数据,更新UI,主要代码如下:
NSOperation的相关知识可以查看http://blog.csdn.net/jasonjwl/article/details/50992720
_parser = [[ParseOperation alloc] initWithData:data]; __weak LazyTableAppDelegate *weakSelf = self; //避免循环引用的常用做法 self.parser.completionBlock = ^(void) { if (weakParser.appRecordList != nil) { //确保主线程更新UI dispatch_async(dispatch_get_main_queue(), ^{ RootViewController *rootViewController = (RootViewController*)[(UINavigationController*)weakSelf.window.rootViewController topViewController]; rootViewController.entries = weakParser.appRecordList; //当解析完成后告诉table view刷新数据 [rootViewController.tableView reloadData]; }); } // 当解析完成后,将队列置为nil weakSelf.queue = nil; }; [self.queue addOperation:self.parser]; // 开始执行解析
1.1 ParseOperation开始解析,会调用文件ParseOperation.m中的main方法,将解析后的结果存储在appRecordList数组
- (void)main { _workingArray = [NSMutableArray array]; _workingPropertyString = [NSMutableString string]; //利用NSXMLParser解析XML NSXMLParser *parser = [[NSXMLParser alloc] initWithData:self.dataToParse]; [parser setDelegate:self]; [parser parse]; if (![self isCancelled]) { // 将解析结果保存在appRecordList self.appRecordList = [NSArray arrayWithArray:self.workingArray]; } self.workingArray = nil; self.workingPropertyString = nil; self.dataToParse = nil; }2.解析XML完成后,赋值rootViewController.entries
= weakParser.appRecordList;通过Block回调通知rootViewController.tableView进行更新。
2.1 在加载cell的时候,做了相应优化 ,如下所示:
当等待cell加载的时候,添加占位cell
当没有缓存images,只有等滚动停止的时候才会让下载器下载图片
如果cell的image正在下载,则返回占位图片
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = nil; NSUInteger nodeCount = self.entries.count; if (nodeCount == 0 && indexPath.row == 0) { // add a placeholder cell while waiting on table data //当等待cell加载的时候,添加占位cell cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier forIndexPath:indexPath]; } else { //重用cell cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; if (nodeCount > 0) { //将每一行cell跟app关联起来 AppRecord *appRecord = (self.entries)[indexPath.row]; cell.textLabel.text = appRecord.appName; cell.detailTextLabel.text = appRecord.artist; //当没有缓存images,只有等滚动停止的时候才会让下载器下载图片 if (!appRecord.appIcon) { if (self.tableView.dragging == NO && self.tableView.decelerating == NO) { [self startIconDownload:appRecord forIndexPath:indexPath]; } //如果cell的image正在下载,则返回占位图片 cell.imageView.image = [UIImage imageNamed:@"Placeholder.png"]; } else { cell.imageView.image = appRecord.appIcon; } } } return cell; }2.2 只有当滚动停止时才加载可见cell的图片
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if (!decelerate) { [self loadImagesForOnscreenRows]; } }2.3 当图片已下载完成时,要避免重复下载
- (void)loadImagesForOnscreenRows { if (self.entries.count > 0) { NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows]; for (NSIndexPath *indexPath in visiblePaths) { AppRecord *appRecord = (self.entries)[indexPath.row]; if (!appRecord.appIcon) // Avoid the app icon download if the app already has an icon { [self startIconDownload:appRecord forIndexPath:indexPath]; } } } }
思考:1.如果图片为圆角图片,该如何优化?
2.除了上述提了的一些优化cell方法,还有那些优化cell的方法。
欢迎大家交流讨论!如有不对的地方,请指出,谢谢!本人正在找iOS方面的工作,如有合适的职位请跟我联系,谢谢!
后续我将带来MJExtension和SDWebImage源码解析系列
LazyTableImages的下载地址:https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html
相关文章推荐
- 20145109 《Java程序设计》第四周学习总结
- Java的几个同步辅助类
- C++学习日志第三篇
- python图片处理Image和skimage的不同
- Java基础--反射机制的知识点梳理
- Java笔记---部署 JavaWeb 项目到云服务器
- java 求解第n个丑数
- Java如何获取所查询的结果集的列数,并将每条记录打印出来
- JAVA常用集合框架用法详解基础篇一之Colletion接口
- 排序
- 理解JNDI中 java:comp/env/jdbc/datasource 与 jdbc/datasource 的不同之处。
- Spring动态连接Mongo(mongo读写分离,连接不同副本集)
- php初探
- Java中finalize方法用途何在?
- Java反射机制探究
- 随堂笔记160322MyEclipse
- Python学习之路--进程,线程,协程
- Java内存结构
- java基础
- Spring学习——(二)IOC、DI以及常用xml配置