转:http://gaohaijun.blog.163.com/blog/static/1766982712011023523125/
在网络应用程序中,经常需要多任务连接来提高程序的性能。比如多任务下载,多任务HTTP请求等,即线程控制模型中的工作群模型。使用 NSOperation 可以很容易实现这个功能。下面就以使用NSOperation处理并行的HTTP请求为例子,说明其用法。
首先准备一个 NSOperation 的子类,用于处理 HTTP 请求。
1 2 3 4 5 6 7 8
|
@interface RequestOperation : NSOperation { NSURLRequest* _request; NSMutableData* _data; }
- (id)initWithRequest:(NSURLRequest *)request;
@end
|
下面是实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
@implementation RequestOperation
- (id)initWithRequest:(NSURLRequest *)request { if (self = [self init]) { _request = [request retain]; _data = [[NSMutableData data] retain]; } return self; }
- (void)dealloc { [_request release]; [_data release]; [super dealloc]; }
// 如果不载下面的函数,会出错 - (BOOL)isConcurrent { return YES; }
// 开始处理 - (void)start { if (![self isCancelled]) { // 以异步方式处理事件 [NSURLConnection connectionWithRequest:_request delegate:self]; } }
// 取得数据 - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { // 添加数据 [_data appendData:data]; }
// HTTP请求结束 - (void)connectionDidFinishLoading:(NSURLConnection*)connection { }
@end
|
如果没有重载 isConcurrent 函数,缺省是返回NO,就是说只能以同步的方式处理。而如果又使用了connectionWithRequest:delegate: 以异步方式处理事件后,会产生下面的错误信息:
1
|
_NSAutoreleaseNoPool(): Object 0x18a140 of class NSURLConnection autoreleased with no pool in place - just leaking
|
然后在你的 Controller 类中用 NSOperationQueue 来处理各个任务。
1 2 3 4 5
|
@interface xxViewController : UIViewController { NSOperationQueue* _queue; }
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
@implementation xxViewController
- (IBAction)buttonClicked:(id) sender { _queue = [[NSOperationQueue alloc] init]; // 第一个请求 NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]]; RequestOperation* operation = [[RequestOperation alloc] initWithRequest:request]; [operation autorelease]; // 第二个请求 NSURLRequest* request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.yahoo.co.jp"]]; RequestOperation* operation2 = [[RequestOperation alloc] initWithRequest:request2]; [operation2 autorelease]; // 开始处理 [_queue addOperation:operation]; }
@end
|
以上,用 NSOperation 来并行处理不同的任务,使用 NSOperationQueue 来控制复数的 NSOperation,并且可以限制Queue的大小,而不是无限制的使用任务。当一个任务完成,就执行待机中的任务。