电动牙刷如何使用用 NSOperations 和 NSOperationQueues

如何使用NSOperations和NSOperationQueues_百度知道
如何使用NSOperations和NSOperationQueues
提问者采纳
由许多线程组成,有一些技术概念需要普及一下。并发就是,但是在管理多线程上面NSThread还是比较头疼,包含了很多可执行指令的集合,你永远不能保证你的代码将会运行在一台能够使用并行处理的的机器上。但是你可以设计你的代码以至于你可以使用并发处理。所以并行和并发其实是两个不同的概念,但是受硬件限制,所以使用的话,并发其实就是多线程)。你应该听说过并发处理和并行处理在开始这篇教程的时候。线程,但是在他们面前只有一把水果刀。并行就是,于是每个人都会轮流来使用这把刀来削水果,由操作系统提供的: 一些需要被处理的简单的工作,知道一些专业术语是很重要的,并且也是操作系统的一部分。所以并行效率会很高,每个人一个水果,线程功能是由POSIX线程API(或者pthreads)提供的,并发是程序的性质。有一个基本的framework包含了一个叫NSThread的类。NSOperation 和NSOperationQueue是一个高度封装的类,是非常容易犯错的: 在一个应用程序里。进程,并行是硬件的性质:作业。作为一个程序员,这个类非常容易使用。这个是相当底层的接口,每个人都可以干自己的事。注意: 一块可执行的二进制代码。(这里简单用一个比喻来说明一下并发和并行。从技术点上来看,简化了操作多线程的难度: 在iphone和mac上面:假如有三个人:有三把水果刀了,而且这个错误是很难被找到的。首先,而不用去等待别人
来自团队:
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁您所在的位置: &
iOS开发ASIHttpRequest创建和执行request
iOS开发ASIHttpRequest创建和执行request
dreamingwish
本文为大家介绍了iOS开发中ASIHttpRequest如何创建和执行request,其中包括同步请求,异步请求,使用Block,使用队列,取消异步请求等等内容。
本文为大家介绍了iOS开发中ASIHttpRequest如何创建和执行request,其中包括同步请求,异步请求,使用Block,使用队列,取消异步请求等等内容。
创建NSOperationQueue,这个Cocoa架构的执行任务(NSOperation)的任务队列。我们通过ASIHTTPRequest.h的源码可以看到,此类本身就是一个NSOperation的子类。也就是说它可以直接被放到任务队列中并被执行。
同步请求会在当前线程中执行,使用error属性来检查结束状态(要下载大文件,则需要设定downloadDestinationPath来保存文件到本地):
-&(IBAction)grabURL:(id)sender&{&&&NSURL&*url&=&[NSURL&URLWithString:@&&];&&&ASIHTTPRequest&*request&=&[ASIHTTPRequest&requestWithURL:url];&&&[request&startSynchronous];&&&NSError&*error&=&[request&error];&&&if&(!error)&{&&&&&NSString&*response&=&[request&responseString];&&&}&}&
同步请求会阻塞主线程的执行,这导致用户界面不响应用户操作,任何动画都会停止渲染。
下面是最简单的异步请求方法,这个request会在全局的NSOperationQueue中执行,若要进行更复杂的操作,我们需要自己创建NSOperationQueue或者ASINetworkQueue,后面会讲到。
-&(IBAction)grabURLInBackground:(id)sender&{&&&&NSURL&*url&=&[NSURL&URLWithString:@&&];&&&&ASIHTTPRequest&*request&=&[ASIHTTPRequest&requestWithURL:url];&&&&[request&setDelegate:self];&&&&[request&startAsynchronous];&}&&-&(void)requestFinished:(ASIHTTPRequest&*)request&{&&&&&&&&NSString&*responseString&=&[request&responseString];&&&&&&&&&NSData&*responseData&=&[request&responseData];&}&&-&(void)requestFailed:(ASIHTTPRequest&*)request&{&&&&NSError&*error&=&[request&error];&}&
在平台支持情况下,ASIHTTPRequest1.8以上支持block。
-&(IBAction)grabURLInBackground:(id)sender&{&&&&NSURL&*url&=&[NSURL&URLWithString:@&&];&&&&__block&ASIHTTPRequest&*request&=&[ASIHTTPRequest&requestWithURL:url];&&&&[request&setCompletionBlock:^{&&&&&&&&&&&&&&NSString&*responseString&=&[request&responseString];&&&&&&&&&&&&&&&NSData&*responseData&=&[request&responseData];&&&&}];&&&&[request&setFailedBlock:^{&&&&&&&NSError&*error&=&[request&error];&&&&}];&&&&[request&startAsynchronous];&}&
注意,声明request时要使用__block修饰符,这是为了告诉block不要retain
request,以免出现retain循环,因为request是会retain block的。
创建NSOperationQueue或者ASINetworkQueue队列,我们还可以设定最大并发连接数:maxConcurrentOperationCount
-&(IBAction)grabURLInTheBackground:(id)sender&{&&&&if&(![self&queue])&{&&&&&&&[self&setQueue:[[[NSOperationQueue&alloc]&init]&autorelease]];&&&&&&&[self&queue].maxConcurrentOperationCount&=&4;&&&&}&&&&&NSURL&*url&=&[NSURL&URLWithString:@&&];&&&&ASIHTTPRequest&*request&=&[ASIHTTPRequest&requestWithURL:url];&&&&[request&setDelegate:self];&&&&[request&setDidFinishSelector:@selector(requestDone:)];&&&&[request&setDidFailSelector:@selector(requestWentWrong:)];&&&&[[self&queue]&addOperation:request];&&}&&-&(void)requestDone:(ASIHTTPRequest&*)request&{&&&&NSString&*response&=&[request&responseString];&}&&-&(void)requestWentWrong:(ASIHTTPRequest&*)request&{&&&&NSError&*error&=&[request&error];&}&
如果不设定selector,那么系统会使用默认的requestFinished:&和&requestFailed:方法
如果需要对队列里面的每个request进行区分,那么可以设定request的userInfo属性,它是个NSDictionary,或者更简单的方法是设定每个request的tag属性,这两个属性都不会被发送到服务器。
不要使用request的URL来区分每个request,因为URL可能会改变(例如重定向),如果需要使用request的URL,使用[request
originalURL],这个将永远返回第一个url。
对于ASINetworkQueue
ASINetworkQueue是NSOperationQueue的子类,提供更高级的特性(ASINetworkQueue的代理函数):
requestDidStartSelector
当一个request开始执行时,这个代理函数会被调用。
requestDidReceiveResponseHeadersSelector
当队列中的request收到服务器返回的头信息时,这个代理函数会被调用。对于下载很大的文件,这个通常比整个request的完成要早。
requestDidFinishSelector
当每个request完成时,这个代理函数会被调用。
requestDidFailSelector
当每个request失败时,这个代理函数会被调用。
queueDidFinishSelector
当队列完成(无论request失败还是成功)时,这个代理函数会被调用。
ASINetworkQueues与NSOperationQueues稍有不同,加入队列的request不会立即开始执行。如果队列打开了进度开关,那么队列开始时,会先对所有GET型request进行一次HEAD请求,获得总下载大小,然后真正的request才被执行。
向一个已经开始进行的ASINetworkQueue 加入request会怎样?
如果你使用ASINetworkQueue来跟踪若干request的进度,只有当新的request开始执行时,总进度才会进行自适应调整(向后移动)。ASINetworkQueue不会为队列开始后才加入的request进行HEAD请求,所以如果你一次向一个正在执行的队列加入很多request,那么总进度不会立即被更新。
如果队列已经开始了,不需要再次调用[queue go]。
当ASINetworkQueue中的一个request失败时,默认情况下,ASINetworkQueue会取消所有其他的request。要禁用这个特性,设置&[queue
setShouldCancelAllRequestsOnFailure:NO]。
ASINetworkQueues只可以执行ASIHTTPRequest操作,二不可以用于通用操作。试图加入一个不是ASIHTTPRequest的NSOperation将会导致抛出错误。
取消异步请求
取消一个异步请求(无论request是由[request startAsynchronous]开始的还是从你创建的队列中开始的),使用[request
cancel]即可。注意同步请求不可以被取消。
注意,如果你取消了一个request,那么这个request将会被视为请求失败,并且request的代理或者队列的代理的失败代理函数将被调用。如果你不想让代理函数被调用,那么将delegate设置为nil,或者使用clearDelegatesAndCancel方法来取消request。
clearDelegatesAndCancel&将会首先清除所有的代理和block。
当使用ASINetworkQueue时,如果取消了队列中的一个request,那么队列中其他所有request都会被取消,可以设置shouldCancelAllRequestsOnFailure的值为NO来避免这个现象。
安全地控制delegate防止request完成之前代理被释放
request并不retain它们的代理,所以有可能你已经释放了代理,而之后request完成了,这将会引起崩溃。大多数情况下,如果你的代理即将被释放,你一定也希望取消所有request,因为你已经不再关心它们的返回情况了。如此做:
&-&(void)dealloc&{&&&&[request&clearDelegatesAndCancel];&&&&[request&release];&&&&...&&&&[super&dealloc];&}
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&&&&&的更多文章
开发者在代码开发和维护中,往往会遇到很多代码优化和内存优化的
既然强大的Android Studio来了,有什么理由不去用呢?
App定价是开发者不可忽视的部分,它是确保应用高能见
微信自引入语音短信功能用户量爆发之后,发展状况一直
Windows Phone开发创建吸引人、带给人快乐并保留用户
该书为C#经典名著!是Wrox红皮书中最畅销的品种之一。从第1版开始就名满天下;其第3版被评选为2005年最权威的十大IT图书之一;并
Windows Phone专家
Android开发专家
51CTO旗下网站70832人阅读
iOS开发进阶(18)
作者同类文章X
前一篇&《》介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用。使用 NSOperation的方式有两种,一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。另一种是继承NSOperation如果你也熟悉Java,NSOperation就和java.lang.Runnable接口很相似。和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。相当与java 中Runnalbe的Run方法。然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。NSInvocationOperation例子:和前面一篇博文一样,我们实现一个下载图片的例子。新建一个Single View app,拖放一个ImageView控件到xib界面。实现代码如下:#import &ViewController.h&
#define kURL @&http://avatar.csdn.net/2/C/D/1_totogo2010.jpg&
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self
selector:@selector(downloadImage:)
object:kURL];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:operation];
// Do any additional setup after loading the view, typically from a nib.
-(void)downloadImage:(NSString *)url{
NSLog(@&url:%@&, url);
NSURL *nsUrl = [NSURL URLWithString:url];
NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];
UIImage * image = [[UIImage alloc]initWithData:data];
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
-(void)updateUI:(UIImage*) image{
self.imageView.image =
}viewDidLoad方法里可以看到我们用NSInvocationOperation建了一个后台线程,并且放到NSOperationQueue中。后台线程执行downloadImage方法。downloadImage 方法处理下载图片的逻辑。下载完成后用performSelectorOnMainThread执行主线程updateUI方法。updateUI 并把下载的图片显示到图片控件中。运行可以看到下载图片显示在界面上。第二种方式继承NSOperation&在.m文件中实现main方法,main方法编写要执行的代码即可。如何控制线程池中的线程数?队列里可以加入很多个NSOperation,&可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。通过下面的代码设置:[queue setMaxConcurrentOperationCount:5];线程池中的线程数,也就是并发操作数。默认情况下是-1,-1表示没有限制,这样会同时运行队列中的全部的操作。著作权声明:本文由原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3515298次
积分:20141
积分:20141
排名:第190名
原创:121篇
转载:14篇
评论:1242条
阅读:75469
文章:15篇
阅读:777656
文章:17篇
阅读:362874
文章:31篇
阅读:1458899
(1)(3)(2)(1)(2)(1)(1)(2)(2)(3)(5)(1)(7)(2)(5)(10)(4)(7)(4)(13)(27)(5)(1)(1)(1)(1)(1)(3)(1)(7)(1)(3)(4)(4)1292人阅读
iPhone常见问题(268)
作者同类文章X
iphone(525)
作者同类文章X
原文地址:/nsoperation/
大家都知道的秘密是一个应用程序,瞬间响应卸载计算在后台异步完成。因此,现代的Objective-C开发者有两种选择:或。
由于GCD已经相当主流,让专注于后者,面向对象的方法。
NSOperation的代表计算的单个单元。这是一个抽象类,让子类状态,优先级,依赖,和消除模型等方面的有用的,线程安全的方式。或者,如果子类是不是你杯茶,总是NSBlockOperation,一个具体的子类,包装业务块。
任务本身的NSOperation的例子包括,调整图像大小,语言处理,或任何其他可重复的,结构性的,长期运行的任务,处理后的数据返回。
但是,简单包装成一个对象的计算并没有做太多,没有一点点的疏忽。这就是NSOperationQueue用武之地。
NSOperationQueue调节操作并发执行。它作为一个优先级队列,执行这样的操作大致先入先出的方式,具有较高的优先级(NSOperation的queuePriority的)那些低优先级的跳跃前进。NSOperationQueue执行操作的同时,选项可以同时执行(maxConcurrentOperationCount)的最大数量限制。
要揭开序幕的NSOperation,你可以调用启动,或将它添加到NSOperationQueue,它会自动开始操作,当它到达队列前面。
走吧NSOperation的不同部位,描述如何使用它们,以及如何实现它们在子类中:
NSOperation的编码相当优雅的状态机来描述执行的操作:
的IsReady&→&→&isFinished的isExecuting
代替一个明确的国有财产,国家确定隐含通过KVO那些keypaths的通知。也就是说,是准备要执行的操作时,它发送一个国际志愿者组织的IsReady码路径,其对应的属性,然后返回YES通知。
每个属性必须是相互排斥的,从一个另一个在为了编码一致的状态:
的IsReady:返回“&是“,以表示该操作已准备好执行,或者,如果为“&否“有一些还没有完成初始化步骤,它是依赖。isExecuting:返回YES如果操作是目前工作在它的任务,否则“&或“&否“。isFinished的回报是如果操作的任务顺利执行完毕,或如果该操作已被取消。一个NSOperationQueue不isFinished的变化是,直到队列中取出的操作,因此它是至关重要的正确,以便实现这个无法避免死锁。
这可能是有用的早期取消操作被执行,以防止不必要的工作。取消的原因可能包括明确的用户操作,或未能在相关的操作。
类似的执行状态,NSOperation的通信取消状态的变化,通过志愿的isCancelled码路径。当操作响应取消命令,它应该清理的任何内部细节,并尽可能快地到达一个合适的最终状态。具体而言,两个isCancelled&isFinished的值需要变成“&YES“&,并且该值的isExecuting&序号。
有一件事一定要注意的是围绕“取消”一词拼写的特殊性。虽然拼写不同方言之间,当它涉及到的NSOperation:
取消的方法使用一个L(动词)isCancelled:使用两个L's的财产(形容词)
所有操作可能无法享受同样重要。将促进设置queuePriority属性或在一个NSOperationQueue根据以下排名推迟的操作:
NSOperationQueuePriorityVeryHighNSOperationQueuePriorityHighNSOperationQueuePriorityNormalNSOperationQueuePriorityLowNSOperationQueuePriorityVeryLow
此外,操作可以指定一个的值的ThreadPriority,这是一个值,该值介于0.0和1.0之间,其中1.0表示最高优先级。鉴于queuePriority确定的顺序操作开始,的的ThreadPriority指定分配的计算,一旦操作已经开始。但与大多数线程的细节,如果你不知道那是什么,你可能并不需要知道一下也无妨。
根据您的应用程序的复杂性,它可能是有意义,瓜分大任务分解成一系列的组合的子任务。你可以做使用NSOperation的依赖。
例如,要描述的过程中,从服务器下载和调整图像大小,你可能会想瓜分网络为一个操作和调整到另一个(或许重用下载其他资源的联网运行,或重用调整操作的图像已经在磁盘上)。然而,不能调整大小的图像,直到其下载。因此,我们说的网络操作是依赖调整大小的操作,前必须完成调整大小操作就可以开始。以代码:
[resizingOperation addDependency:networkingOperation];
[operationQueue addOperation:networkingOperation];
[operationQueue addOperation:resizingOperation];
操作将无法启动,直到所有依赖返回YES&isFinished的。重要的是要记住的依赖关系图中所涉及的所有的操作添加到操作队列,以免沿途的某个地方一定的差距。
另外,确保不会意外产生依赖关系循环,使得A依赖于B,和B依赖于A,例如。这将创建死锁和悲伤。
completionBlock
一个非常有用的功能中添加了块复兴的iOS 4和雪豹是财产completionBlock。
一个NSOperation的完成时,它将执行其正是completionBlock一次。这提供了一个非常好的方法,模型中使用自定义的操作行为时,或查看控制器。例如,你可以在网络上完成块操作块做一些与服务器的响应数据,一旦其完成加载。
NSOperation的仍然是一个必不可少的工具,在现代的Objective-C程序员一袋招数。而GCD线异步处理的理想选择,NSOperation的提供更全面的,面向对象的模型的计算,这是理想的封装周围结构,可重复的任务,在应用程序中的所有数据。将它添加到你的下一个项目,不仅是对你的用户带来喜悦,但自己!
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1057777次
积分:13570
积分:13570
排名:第433名
原创:177篇
转载:854篇
译文:44篇
评论:149条
(4)(13)(15)(19)(9)(3)(9)(3)(2)(7)(5)(1)(3)(14)(24)(20)(28)(14)(21)(19)(36)(26)(18)(21)(35)(49)(23)(60)(38)(33)(51)(49)(58)(44)(67)(31)(44)(70)(90)(1)

我要回帖

更多关于 如何使用itunes 的文章

 

随机推荐