NSOperation和NSOperationQueue

NSOperation和NSOperationQueue,第1张

概述多线程(NSOperation和NSOperationQueue) 在网络应用程序中,经常要使用多任务处理来提高应用程序的性能,即在同一时间,有多个处理同时进行。例如,同时进行多个文件下载,同时进行多个HTTP请求等。这一般都 是通过多线程完成的。另外,多线程编程也是为了防止主线程堵塞,增加运行效率的方法。比如,如果主线程从网上下载一个很大的图片,那么,给用户的感觉是整个应用程序死掉了。所以,可以 多线程(NSOperation和NSOperationQueue)
在网络应用程序中,经常要使用多任务处理来提高应用程序的性能,即在同一时间,有多个处理同时进行。例如,同时进行多个文件下载,同时进行多个http请求等。这一般都 是通过多线程完成的。另外,多线程编程也是为了防止主线程堵塞,增加运行效率的方法。比如,如果主线程从网上下载一个很大的图片,那么,给用户的感觉是整个应用程序死掉了。所以,可以把这个下载 *** 作放在一个线程中,在主线程中调用这个线程让它在后台处理,主线程序可以显示一些其他信息,比如显示一些“正在装载”等文字信息。
在Cocoa中,NSOperation类提供了一个优秀的多线程编程方法。很多编程语言都支持多线程处理应用程序,但是多线程程序往往一旦出错就会很难处理。庆幸的是,苹果公司在这方面做了很多改进,例如在NSThread上新增了很多方法,还新增了两个类NSOperation 和NSOperationQueue,从而让多线程处理变得更加容易。
在多线程中,可以同时进行多个 *** 作。NSOperation对象就是一个 *** 作,比如,装载网页内容的一个 *** 作。在Objective-C上,一个具体的 *** 作(比如网页装载)是一个继承NSOperation 的类。在这个类中,至少需要重写一个-(voID)main方法。线程(NSOperation)自动调用main 方法,main方法就是线程要执行的具体 *** 作。在下面的例子中,PageLoadOperation 继承了NSOperation,并实现了main方法。一般而言,可以利用其初始化方法来传入所需要的参数和对象,比如PageLoadOperation的initWithURL:方法用来设置要装载的网址。
使用NSOperation 的最简单方法就是将其放入NSOperationQueue中,NSOperationQueue是存放多个 *** 作的队列。一旦一个NSOperation对象被加入NSOperationQueue,该队列就会启动并开始处理它(即调用它的main方法),当 *** 作完成后,队列就会释放它。
下面创建一个CocoaApplication例子来演示使用NSOperation和NSOperationQueue完成多线程处理。
应用代理类AppDelegate.h的代码如下:
#import<Cocoa/Cocoa.h>  @interface AppDelegate : NSObject {   NSOperationQueue *queue; //线程队列   }   + (ID)shared;   - (voID)pageLoaded:(NSXMLdocument*)document;  @end     AppDelegate.m的代码如下:     #import "AppDelegate.h"   #import "PageLoadOperation.h"   @implementation AppDelegate   static AppDelegate *shared;   static NSArray *urlArray;   - (ID)init   {   if (shared) {   [self autorelease];   return shared;   }   if (![super init]) return nil;   //设置要访问的网址   NSMutableArray *array = [[NSMutableArray alloc] init];  [array addobject:@"http://www.xinlaoshi.com"];  [array addobject:@"http://www.yunwenjian.com"];  [array addobject:@"http://www.108fang.com"];  [array addobject:@"http://www.baIDu.com"];  urlArray = array;   //[queue setMaxConcurrentoperatio nCount:2];  queue = [[NSOperationQueue alloc] init];  shared = self;   return self;   }   - (voID)applicationDIDFinishLaun ching:(NSNotification*)aNotification   { //把各个 *** 作添加到队列中   for (Nsstring *urlString in urlArray) {  NSURL *url = [NSURL URLWithString:urlString];  PageLoadOperation *plo = [[PageLoadOperation alloc]  initWithURL:url];   [queue addOperation:plo];   [plo release];   }   }   - (voID)dealloc   {   [queue release],queue = nil;   [super dealloc];   }   + (ID)shared;   {   if (!shared) {   [[AppDelegate alloc] init];   }   return shared;   }   //用于打印网页内容   - (voID)pageLoaded:(NSXMLdocument*)document;  {   NSLog(@"xml 文档是:%@",document);   }   @end  线程 *** 作类PageLoadOperation.h的代码如下:
#import<Cocoa/Cocoa.h>  @interface PageLoadOperation : NSOperation {  //需要使用多线程的类要继承NSOperation   NSURL *targetURL;   }   @property(retain) NSURL *targetURL;   - (ID)initWithURL:(NSURL*)url;   @end     PageLoadOperation.m的代码如下:     #import "PageLoadOperation.h"   #import "AppDelegate.h"   @implementation PageLoadOperation   @synthesize targetURL;   //获取要访问的网址   - (ID)initWithURL:(NSURL*)url;   {   if (![super init]) return nil;   [self setTargetURL:url];   return self;   }   - (voID)dealloc {   [targetURL release],targetURL = nil;   [super dealloc];   }   //线程完成的 *** 作。本例访问网址,并把该网址的内容放到一个NSXMLdocument 对象上  - (voID)main {   //将targetURL 的值返回为webpageString 对象   Nsstring *webpageString = [[[Nsstringalloc]initWithContentsOfURL:   [self targetURL]] autorelease];   NSError *error = nil;   //访问网址,并把该网址的网页内容放到一个NSXMLdocument 对象上  NSXMLdocument *document = [[NSXMLdocument alloc]initWithXMLString:   webpageString options:NSXMLdocumentTIDyHTMLerror:&error];   if (!document) {   //当document 为nil 的时候打印错误信息   NSLog(@"错误信息:(%@): %@",[[self targetURL] absoluteString],  error);   return;   }   //拿到AppDelegate 对象并且调用主线程上的打印方法   [[AppDelegate shared]   performSelectorOnMainThr ead:@selector(pageLoaded:)  withObject:document   waitUntilDone:NO];   }   @end  【程序结果】
xml 文档是:<!DOCTYPE HTML PUBliC "-//W3C//DTDxhtml 1.0   Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-  Transitional.dtd"><HTMLxmlns=" http://www.w3.org/1999/xhtml"><head><Meta  http-equiv="Content-Type" content=" text/HTML; charset=utf-8"/><Title>新老  师-学网上课程交圈内朋友</Title>  ....   xml 文档是:<!DOCTYPE HTML PUBliC "-//W3C//DTDxhtml 1.0   Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-  Transitional.dtd"><HTML><head><Title>云文件</Title>  ....   xml 文档是:<!DOCTYPE HTML PUBliC "-//W3C//DTDxhtml 1.0   Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-  Transitional.dtd"><HTMLxmlnsHTMLxmlns=" http://www.w3.org/1999/xhtml"><head><Meta  http-equiv="Content-Type" content="text/HTML; charset=utf-8"/>  <Title>108方手机应用平台</Title>  ....   xml 文档是:<!DOCTYPEHTML><HTML><head><Metahttp-equiv="Content-Type"  content="text/HTML;charset=gb2312"><Title>百度一下,你就知道</Title>  下面分析一下这段程序执行过程,由于是一个Cocoa Application应用程序,所以系统会先执行委托类AppDelegate 下的初始化方法- (ID)init进行一些初始化设置。在这个委托方法上,首先判断shared是否已经初始化过。若初始化过,则直接返回结果;若是应用程序第一次调用初始化方法,则就初始化urlArray数组,并将要用线程访问的各个网站地址装入其中,随后初始化shred 和NSOperationQueue的对象queue。在应用装载结束以后,系统会调用另一个委托方法applicationDIDFinishLaun ching:方法,在这个方法中,我们遍历存入urlArray数组中的网站地址字符串,将其依次转换为NSURL对象。与此同时,创建同等数量的PageLoadOperation对象,并将转换好的NSURL 对象设置为各个PageLoadOperation对象的属性targetURL。我们还将初始化好的PageLoadOperation对象加入到queue队列上。
在队列中每加入一个线程 *** 作后,队列都会为其分配一个NSThread来启动它,并运行 *** 作的main方法。一旦 *** 作完成,线程就会报告给队列以让队列释放该 *** 作。
在PageLoadOperation 类的main 方法上,根据前面设置好的targetURL属性值,将该网址转换为字符串对象webpageString,并且加入自动释放池。利用转换好的webpageString对象初始化NSXMLdocument对象,并访问这个网站,把内容放在NSXMLdocument对象上。如果在加载网站内容过程中发生错误,就会打印错误信息。如果没有错误,就调用主线程的pageLoaded方法,从而打印网页内容到控制台上,然后任务结束。队列会在main 方法结束后自动释放该线程。
这个例子展示了NSOperation 和NSOperationQueue最基本的使用。实例中的大部分代码与NSOperation 和NSOperationQueue的设定和使用无关,都是一些业务实现代码。NSOperation本身所需要的代码非常少,但是通过这少量的代码就可以在应用中轻松地使用多线程,从而为用户提供更好的并发性能。另外,在init方法中,有一句代码:
//[queuesetMaxConcurrentoperatio nCount:2];  这是用来设置线程的个数。如果去掉上面的注释,那么,线程队列就被限制为只能同时运行两个 *** 作,剩余的 *** 作就需要等待这两个 *** 作中的任一个完成后才有可能被运行。 总结

以上是内存溢出为你收集整理的NSOperation和NSOperationQueue全部内容,希望文章能够帮你解决NSOperation和NSOperationQueue所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1055110.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存