NSOperation
Apple在OS X 10.5 Leopard上做了很多改进。NSThread
本身就新增了很多新的方法,从而使得多线程变得更加容易。此外还新增了NSOperation
和NSOperationQueue
两个类,使多线程编程更加方便!
以NSOperation
和NSOperationQueue
为例
1.头文件
1
2
3
4
5
6
7
8
9
10
11
|
// QTileDownloadOperation.h
#import <Foundation/Foundation.h>
@interface QTileDownloadOperation : NSOperation
@property(nonatomic, retain)NSString* name;
- (void)clear;
@end
|
2.实现文件
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
// QTileDownloadOperation.m
#import "QTileDownloadOperation.h"
@implementation QTileDownloadOperation
@synthesize name;
- (void)dealloc {
[name release];
//......
[super dealloc];
}
- (void)main
{
if ([self isCancelled] || [self isFinished]) {
return;
}
NSLog(@"%@start!",name);
NSString* urlString = [@"你得URL" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL* url = [NSURL URLWithString:urlString];
NSMutableURLRequest* requestWithAgent = [NSMutableURLRequest requestWithURL:url];
[requestWithAgent setValue:@"mapapi" forHTTPHeaderField:@"User-Agent"];
[requestWithAgent setTimeoutInterval:120];
NSError* error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:requestWithAgent returningResponse:nil error:&error];
if (error == nil) {
if (![self isCancelled])
{
[self didFinishWithData:data];
}
}
else
{
//error handle
//对外通知,注意线程同步
}
}
- (void)didFinishWithData:(NSData*)data
{
NSLog(@"%@complete!",name);
//数据处理.........................
//对外通知,注意线程同步
}
- (void)clear
{
//可以进行取消网络,delegate置为nil,清理其他资源等。主要是防止线程对象释放时Crash
}
@end
|
3.可以使用创建的OperationQueue
管理线程对象
1
2
3
4
5
|
NSOperationQueue* q = [[NSOperationQueue alloc] init];
self.myQueue = q;
//设置允许最大并发数
[myQueue setMaxConcurrentOperationCount:2];
[q release];
|
向NSOperationQueue
中添加QTileDownloadOperation
对象
1
2
3
4
5
6
7
8
|
for (int i = 0; i < 8; ++i) {
QTileDownloadOperation* op = [[QTileDownloadOperation alloc] init];
NSString* name = [NSString stringWithFormat:@"op%d",i];
op.name = name;
[myQueue addOperation:op];
[op release];
}
|
释放线程队列
1
2
3
4
5
6
7
8
9
10
11
12
13
|
NSArray *allOperations = [myQueue operations];
for (QTileDownloadOperation* op in allOperations) {
if(![op isCancelled])
{
[op clear];
[op cancel];
}
}
[myQueue release];
myQueue = nil;
|
4.如何是取消NSOperation
通常情况下,取消当前线程队列中当前待执行线程队列队首尚未取消的线程对象。如下所示:
1
2
3
4
5
6
7
8
9
10
|
NSArray *allOperations = [myQueue operations];
for (int i = [myQueue maxConcurrentOperationCount]; i < [allOperations count]; ++i) {
QTileDownloadOperation* op = [allOperations objectAtIndex:i];
if (!op.isCancelled) {
[op clear];
[op cancel];
}
}
|
为什么会allOperations暂存呢?
因为线程队列中的对象在并发执行,其状态在任意时间点可能会改变。
而这个取消的操作通常在其他线程中,比如说主线程,会因线程不同步引发Crash等异常。
文章作者
梵梵爸
上次更新
2013-04-03
许可协议
原创文章,如需转载请注明文章作者和出处。谢谢