使用NSOperation和NSOperationQueue启动多线程开发应用
来源:互联网 发布:黑马java视频教程2017 编辑:程序博客网 时间:2024/05/27 02:26
Apple从os x10.5在多线程应用的开发上有了很多改进,NSThread的引入使得开发多线程应用程序变得容易多了,尤其是引入了两个全新的类:NSOperation和NSOperationQueue。NSOperation对象类似java.lang.Runnable接口,也被设计为可扩展的,而且只有一个需要重写的方法。这就是-(void)main。
使用NSOperation的最简单的方式就是把一个NSOperation对象加入到NSOperationQueue队列中,一旦这个对象被加入到队列,队列就开始处理这个对象,直到这个对象的所有操作完成,然后它被队列释放。下面示例:使用一个获取网页,并对其解析的线程NSXMLDocument,最后将解析得到的NSXMLDocument再返回给主线程。
// PageLoadOperation.h@interface PageLoadOperation : 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]; [super dealloc];}- (void)main{ NSString *webpageString = [[[NSString alloc] initWithContentsOfURL:[self targetURL]] autorelease]; NSError *error = nil; NSXMLDocument *document = [[NSXMLDocument alloc] initWithXMLString:webpageString options:NSXMLDocuemtTidyHTML error:&error]; if (!document){ NSLog(@"%s Error loading document(%@):%@",_cmd,[[self targetURL] absoluteString], error]; return; } [[AppDelegate shared] performSelectorOnMainThread:@selector(pageLoaded:) withObject:document waitUntilDon:YES]; [document release];}@end
正是这样,该类很简单,只是在其init方法中接受一个url并保存起来,当main函数被调用的时候,它使用这个保存的url创建一个字符串,并将其传递给NSXMLDocumentinit方法。如果加载的xml数据没有出错,数据会被传递给AppDelegate,它处于主线程中。到此,这个线程的任务就宣告完成了。在主线程中注销操作队列时,会将这个NSOperation对象释放。
// AppDelegate.h@interface AppDelegate : NSObject { NSOperationQueue *queue;}+ (id)shared;- (void)pageLoaded:(NSXMLDocument *)document;@end//AppDelegate.m#import "AppDelegate.h"#import "PageLoadOperation.h"@implementation AppDelegatestatic 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.google.com"]; [array addObject:@"http://www.apple.com"]; [array addObject:@"http://www.yahoo.com"]; [array addObject:@"http://www.zarrastudios.com"]; [array addObject:@"http://www.macosxhints.com"]; urlArray = array; queue = [[NSOperationQueue alloc] init]; shared = self; return self;}- (void)applicationDidFinishLaunching:(NSNotification *)aNatification{ 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]; [super dealloc];}+ (id)shared{ if(!shared){ [[AppDelegate alloc] init]; } return shared;}- (void)pageLoaded:(NSXMLDocument *)document{ NSLog(@"%s Do something with the XMLDocuemt:%@",_cmd,document);}@end
实践问题:在iOS4.0后,如果是并发操作则NSURLConnection无法在NSOperation中正常运行了。即NSURLConnection只能运行于主线程。解决方法可以借鉴以下代码:
-(void)download{ // NSURLConnectionn won't work if it's not in the main thread if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(download) withObject:nil waitUntilDone:NO]; return; } NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:_urlString]]; _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; }
这个问题,其实确切是在iOS3中,并发的Operation都是在主线程中执行的,而到了iOS4.0,并发的Operation会在一个独立的线程中执行,这样就产生问题,如果不做特殊的处理,当Operation有异步的调用时,比如NSURLConnection,会由于Operation的start执行之后线程退出了而导致收不到相关的delegate调用。这个问题的标准解决之道是:在NSOperation发出了异步请求之后,启动线程内的runloop。确保线程不退出,同时收到delegate调用。
- 使用NSOperation和NSOperationQueue启动多线程开发应用
- 使用NSOperation和NSOperationQueue启动多线程开发应用
- 使用NSOperation和NSOperationQueue启动多线程开发应用
- 使用NSOperation和NSOperationQueue启动多线程
- 使用NSOperation和NSOperationQueue启动多线程
- 使用NSOperation和NSOperationQueue启动多线程
- 使用NSOperation和NSOperationQueue启动多线程
- 使用NSOperation和NSOperationQueue启动多线程
- 使用NSOperation和NSOperationQueue启动多线程
- 使用NSOperation和NSOperationQueue启动多线程的教程
- 使用NSOperation和NSOperationQueue启动多线程的教程
- 多线程NSOperation和NSOperationQueue
- 使用NSOperation和NSOperationQueue用来实现多线程
- 多线程的使用(2) - NSOperation和NSOperationQueue
- iOS多线程 NSOperation和NSOperationQueue的使用
- 多线程的使用(2) - NSOperation和NSOperationQueue
- 多线程的使用(2) - NSOperation和NSOperationQueue
- iOS开发-NSOperation和NSOperationQueue的使用
- 通过xerces来验证xml是否匹配xsd的java示例
- 字符编码
- weblogic.rjvm.RJVMImpl@dc02e8系统问题,导致应用极慢
- 基于贪心算法的几类区间覆盖问题
- 模式识别初体验——模式识别中要处理的问题以及使用的方法
- 使用NSOperation和NSOperationQueue启动多线程开发应用
- 【Object-C】内存管理小结
- 10591 - Happy Number
- 我们应当怎样做需求分析:原文分析法(17)
- Web Service
- c语言中数组的初始化
- TCP、UDP、HTTP、SOCKET之间的区别
- Doxygen + Graphviz windows下安装配置(图解)
- [Python]类属性与实例属性