使用NSOperation为你的app加速

app store中的很多应用程序非常的笨重,他们有好的界面,但操作性很差,比如说当程序从网上或本地载入数据的时候,界面被冻结了,用户只能等程序完全载入数据之后才能进行操作。
当打开一个应用程序时,iphone会产生一个包含main方法的线程,所用程序中的界面都是运行在这个线程之中的(table views, tab bars, alerts…),有时候我们会用数据填充这些view,现在问题是如何有效的载入数据,并且用户还能自如的操作程序。
下面要说方法的并不是要在用户载入数据的时候在界面上提示“loading”的信息,虽然这种方式在有些时候是可以被接受的,但当数据在main线程之外被载入是并不是最有效的方式。
先看一下要演示的程序:


这个程序将从网络上下载10,000条数据,并填入到UITableView中,现面的代码将首先演示一种错误的方式:
错误 (源码 )

 
@implementationRootViewController
@synthesizearray;-(void)viewDidLoad {[super viewDidLoad];/* Adding the button */self.navigationItem.rightBarButtonItem =[[UIBarButtonItem alloc]initWithTitle:@"Load"style:UIBarButtonItemStyleDone
target:selfaction:@selector(loadData)];/* Initialize our array */NSMutableArray*_array =[[NSMutableArrayalloc]initWithCapacity:10000];
self.array=_array;
[_array release];
}// Fires when the user presses the load button-(void)loadData {/* Grab web data */NSURL*dataURL =[NSURLURLWithString:@"http://icodeblog.com/samples/nsoperation/data.plist"];NSArray*tmp_array =[NSArrayarrayWithContentsOfURL:dataURL];/* Populate our array with the web data */for(NSString*str intmp_array){[self.arrayaddObject:str];
}/* reload the table */[self.tableViewreloadData];
}#pragma mark Table view methods-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{return1;
}-(NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section {return[self.arraycount];
}-(UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*CellIdentifier =@"Cell";UITableViewCell *cell=[tableViewdequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier]autorelease];
}/* Display the text of the array */[cell.textLabel setText:[self.arrayobjectAtIndex:indexPath.row]];returncell;
}-(void)dealloc{[super dealloc];
[arrayrelease];
}@end


当点击“load”按钮时程序会被冻结,直到将数据完全下载并填入Tableview,在这期间用户不能做任何的事情。
在给出解决方式之前先来看一下NSOperationQueue和NSOperation:

The NSOperation and NSOperationQueue classes  alleviate much of the pain of multi-threading, allowing you to simply  define your tasks, set any dependencies that exist, and fire them off.  Each task, or operation , is represented by an instance  of an NSOperation class; the NSOperationQueueclass  takes care of starting the operations, ensuring that they are run in  the appropriate order, and accounting for any priorities that have been  set.

下面要做的是建立NSOperationQueue和NSOperations。NSOperationQueue会建立一个线程,每个加入到线程operation会有序的执行。
下面是使用NSOperationQueue的过程:

  1. 建立一个NSOperationQueue的对象
  2. 建立一个NSOperation的对象
  3. 将operation加入到NSOperationQueue中
  4. release掉operation

使用NSOperation有几种,现在介绍最简单的一种NSInvocationOperation,NSInvocationOperation是NSOperation的子类,允许运行在operation中的targer和selector。  下面是执行NSInvocationOperation的一个例子:

 
NSOperationQueue*queue =[NSOperationQueuenew];NSInvocationOperation*operation=[[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(methodToCall)object:objectToPassToMethod];[queue addOperation:operation];
[operationrelease];


下面是我们用正确的方式实现的程序:
正确的方式(下载源码 )

 
@implementationRootViewController
@synthesizearray;-(void)viewDidLoad {[super viewDidLoad];self.navigationItem.rightBarButtonItem =[[UIBarButtonItem alloc]initWithTitle:@"Load"style:UIBarButtonItemStyleDonetarget:selfaction:@selector(loadData)];NSMutableArray*_array =[[NSMutableArrayalloc]initWithCapacity:10000];self.array=_array;[_array release];
}-(void)loadData {/* Operation Queue init (autorelease) */NSOperationQueue*queue =[NSOperationQueuenew];/* Create our NSInvocationOperation to call loadDataWithOperation, passing in nil */NSInvocationOperation*operation=[[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(loadDataWithOperation)object:nil];/* Add the operation to the queue */[queue addOperation:operation];[operationrelease];
}-(void)loadDataWithOperation {NSURL*dataURL =[NSURLURLWithString:@"http://icodeblog.com/samples/nsoperation/data.plist"];NSArray*tmp_array =[NSArrayarrayWithContentsOfURL:dataURL];for(NSString*str intmp_array){[self.arrayaddObject:str];}[self.tableViewreloadData];
}#pragma mark Table view methods-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{return1;
}-(NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section {return[self.arraycount];
}-(UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*CellIdentifier =@"Cell";UITableViewCell *cell=[tableViewdequeueReusableCellWithIdentifier:CellIdentifier];if(cell==nil){cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease];}[cell.textLabel setText:[self.arrayobjectAtIndex:indexPath.row]];returncell;
}-(void)dealloc{[super dealloc];[arrayrelease];
}


再次运行程序,当点击“load”按钮时界面是否还被“冻结”呢,程序并没有增加很多的代码,但确大大的提高了用户体验。

转载于:https://www.cnblogs.com/zhwl/archive/2013/01/05/2845281.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode43——Multiply Strings(两个字符串表示的整数相乘)???

题目: 参考解法: 法一: This is the standard manual multiplication algorithm. We use two nested for loops, working backward from the end of each input number. We pre-allocate our result and accumulate our partial result in …

Windows-server-2008-R2安装Oracle-11g-R2-dataguard

一、安装环境 1、服务器环境:Windows server 2008 R2 x64 Standard 两台 CPU:8核 内存:8G 硬盘空间:1060G 2、软件:oracle 11g R2 二、安装前配置 1、IP地址配置要求 主库IP:192.168.2.50 备库IP&#xff1…

LeetCode66——Plus One(一个整数用数组存储,然后在末尾加1)

题目&#xff1a; 参考解法&#xff1a; class Solution { public:vector<int> plusOne(vector<int>& digits) {bool carry true;for(int idigits.size()-1; i > 0 && carry; i--) {carry (digits[i]%10) 0;}if(carry) {digits.insert(digits.be…

项目中CI缓存适配器的使用

2019独角兽企业重金招聘Python工程师标准>>> 项目中CI缓存适配器的使用 项目中有若干控制器&#xff0c;这些控制器有一些公共数据&#xff0c;因此&#xff0c;在基控制器类中获取这些数据&#xff0c;为了提高系统性能&#xff0c;使用了缓存系统&#xff0c;采…

康奈尔笔记法

一页有三栏&#xff1a;主栏、副栏、思考栏。主栏主要是在右上角&#xff0c;主要记录学到的内容。副栏在左边&#xff0c;主要是简单概括重点。思考栏在底部&#xff0c;主要是记录收获、感悟。 主栏&#xff1a;在听讲或阅读时把重要的内容或知识的要点记录在右侧的区域&…

Memcached 内存管理(一)

2019独角兽企业重金招聘Python工程师标准>>> Memcached是一个高效的分布式内存cache&#xff0c;了解memcached的内存管理机制&#xff0c;便于我们理解memcached&#xff0c;让我们可以针对我们数据特点进行调优&#xff0c;让其更好的为我所用。这里简单谈一下我对…

jitter 如何优化网络_网络推广如何做好网站SEO优化

网络推广做好网站整站SEO优化的方式有很多&#xff0c;如何才能做好SEO优化&#xff1f;网络推广如何做好网站SEO优化一、定位网站关键词SEO给一个网站刚开始做优化的时候&#xff0c;不是立马就设置关键词&#xff0c;而是先分析该网站主要是做什么产品/服务。知道网站的目的是…

PHP+Mysql查询上一篇和下一篇文章实例

PHPMysql查询上一篇和下一篇文章实例 简单的PHPMysql查询上一篇和下一篇文章实例&#xff0c;并输出上一篇和下一篇文章的标题和链接&#xff0c;适合新手学习获取当前浏览文章id&#xff1a; 1 $id isset($_GET[id]) > 0 ? intval($_GET[id]) : ""; 下一篇文章…

openssh-在win7上的搭建

2019独角兽企业重金招聘Python工程师标准>>> 参考 http://www.cnblogs.com/ericsun/archive/2012/06/10/2544413.html 1.下载OpenSSH&#xff1a;http://sourceforge.net/projects/sshwindows/files/OpenSSH%20for%20Windows%20-%20Release/3.8p1-1%2020040709%20B…

LeetCode8——String to Integer (atoi)(自己编写atoi函数)

题目&#xff1a; 参考解法&#xff1a; I think we only need to handle four cases: discards all leading whitespaces sign of the number overflow invalid input int myAtoi(char* str) {int sign 1, base 0, i 0;while (str[i] ) { i; }//去掉空格if (str[i…

5类6类7类网线对比_孩子们长高的黄金时期是从3月到5月,这阶段多吃6类食物长得快...

原标题&#xff1a;孩子们长高的黄金时期是从3月到5月&#xff0c;这阶段多吃6类食物长得快每个家长都希望孩子长大。当他们看到自己的孩子比同龄的孩子矮时&#xff0c;他们会非常担心。他们特别担心孩子的成长。事实上&#xff0c;儿童的生长发育有明显的季节性&#xff0c;一…

快速地创建快顶尖的医学图像处理控件ImageGear Medical

ImageGear Medical控件使开发人员能够快速地创建快顶尖的医学图像处理控件&#xff0c;可以对DICOM文件进行浏览、创建、编辑&#xff0c;可以控制图像所有切面显示和打印&#xff0c;对图像进行注释&#xff0c;以及支持ISIS和TWAIN扫描和100多种图像文件格式&#xff0c;可用…

jj为什么会变大变小_为什么上过太空的种子果实会变大?射线会让生物向大变异吗?...

在科幻电影中&#xff0c;变异是不正常力量的重要来源之一&#xff0c;所谓“富人靠科技&#xff0c;穷人靠变异&#xff01;”。但其实科幻在某种意义上一起在误导着我们&#xff0c;多数科幻作品其实是以科学为外衣的魔法故事&#xff0c;比如“爱你三千遍”的钢铁侠&#xf…

CutJS – 用于 HTML5 游戏开发的 2D 渲染引擎

CutJS 是轻量级的&#xff0c;快速的&#xff0c;基于 Canvas 开发的 HTML5 2D 渲染引擎&#xff0c;可以用于游戏开发。它是开源的&#xff0c;跨平台的&#xff0c;与现代的浏览器和移动设备兼容。CutJS 提供了一个类似 DOM 树的数据模型来编写应用程序&#xff0c;并在内部…

LeetCode65——Valid Number(使用DFA)来判断字符串是否为数字

题目&#xff1a; 参考解法&#xff1a;&#xff08;DFA&#xff09; class Solution { public:bool isNumber(string str) {int state0, flag0; // flag to judge the special case "."while(str[0] ) str.erase(0,1);//delete the prefix whitespace while(str[s…

win10商店下载位置_Win10删应用商店下载记录|Win10删Microsoft Store下载记录

Win10中的Microsoft Store&#xff0c;也称微软应用商店&#xff0c;提供给Windows用户下载安装使用各种应用&#xff0c;因此有些用户&#xff0c;会在这里下载软件&#xff0c;不过&#xff0c;在使用时间长了&#xff0c;也是会产生下载记录的。这篇文章是PE吧给大家带来的W…

【原创】什么是 wire protocol

2019独角兽企业重金招聘Python工程师标准>>> 究竟 wire protocol 是指什么&#xff1f;下面这段话可以比较清楚的解释&#xff08;原本来自 这里 &#xff09;。 In a network, a wire protocol is the mechanism for transmitting data from point a to point b. T…

上机环境是什么意思_Python能不能自学,可以找到什么工作?

1、学习Python能够找到什么样的工作&#xff1f;Python 编程有很多方向&#xff0c;有网络爬虫、数据分析、Web开发、测试开发、运维开发、机器学习、人工智能、量化交易等等&#xff0c;各个方向都有特定的技能要求&#xff0c;比如学数据分析就要重点掌握统计学、SQL 等知识&…

mysql 优化之 is null ,is not null 索引使用测试

关于mysql优化部分&#xff0c;有很多网友说尽量避免使用is null, is not null,select * 等&#xff0c;会导致索引失效&#xff0c;性能降低&#xff1f;那是否一定收到影响呢&#xff1f;真的就不会使用索引了吗&#xff1f; 本文的测试数据库版本为5.7.18&#xff0c;不同版…

LeetCode7——Reverse Integer(将一个整数反转,注意溢出的处理)

题目&#xff1a; 解法一&#xff1a; 注意long long类型&#xff0c;表示64bit数字。 解法二&#xff1a; class Solution { public:int reverse(int x) {int ans 0;while (x) {int temp ans * 10 x % 10;if (temp / 10 ! ans)//溢出后&#xff0c;这里就会不成立了return …