并发执行operation
使用opération queue 或 子类化NSOperation 并在main方法里面detach一个线程来执行。
- (void) firstOperationEntry:(id)paramObject{
NSLog(@"%s", __FUNCTION__);
NSLog(@"Parameter Object = %@", paramObject);
NSLog(@"Main Thread = %@", [NSThread mainThread]);
NSLog(@"Current Thread = %@", [NSThread currentThread]);
}
- (void) secondOperationEntry:(id)paramObject{
NSLog(@"%s", __FUNCTION__);
NSLog(@"Parameter Object = %@", paramObject);
NSLog(@"Main Thread = %@", [NSThread mainThread]);
NSLog(@"Current Thread = %@", [NSThread currentThread]);
}
NSOperationQueue *operationQueue;
NSInvocationOperation *firstOperation;
NSInvocationOperation *secondOperation;
-(void)test6_13
{
NSNumber *firstNumber = [NSNumber numberWithInteger:111];
NSNumber *secondNumber = [NSNumber numberWithInteger:222];
firstOperation =[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstOperationEntry:) object:firstNumber];
secondOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(secondOperationEntry:) object:secondNumber];
operationQueue = [[NSOperationQueue alloc] init];
/* Add the operations to the queue */
[operationQueue addOperation:firstOperation];
[operationQueue addOperation:secondOperation];
NSLog(@"Main thread is here");
}
输出
2014-03-11 17:08:00.381 cookbook[547:360b] -[AppDelegate secondOperationEntry:]
2014-03-11 17:08:00.381 cookbook[547:a0b] Main thread is here
2014-03-11 17:08:00.381 cookbook[547:1403] -[AppDelegate firstOperationEntry:]
2014-03-11 17:08:00.382 cookbook[547:360b] Parameter Object = 222
2014-03-11 17:08:00.383 cookbook[547:1403] Parameter Object = 111
2014-03-11 17:08:00.384 cookbook[547:360b] Main Thread = <NSThread: 0x896ec60>{name = (null), num = 1}
2014-03-11 17:08:00.385 cookbook[547:1403] Main Thread = <NSThread: 0x896ec60>{name = (null), num = 1}
2014-03-11 17:08:00.385 cookbook[547:360b] Current Thread = <NSThread: 0x8c76570>{name = (null), num = 2}
2014-03-11 17:08:00.385 cookbook[547:1403] Current Thread = <NSThread: 0xdb5d2f0>{name = (null), num = 3}
可以看出主线程没有被锁
如何来写自己的NSOperation呢,有几点要注意
1,因为加到opération queue以后,opération 将异步运行,所以必须重写isConcurrent方法,并返回yes
2,注意此operation 是否被取消,在main之前以及执行任务过程中要注意此操作是否已经取消了。
3,重写main方法,并在里面使用自动释放池
4,重写is finished 和isExecuting 方法。
.h文件
@interface SimpleOperation : NSOperation
/* Designated Initializer */
- (id) initWithObject:(NSObject *)paramObject;
@end
.m文件
@implementation SimpleOperation
NSObject *givenObject;
BOOL finished;
BOOL executing;
- (id) init {
NSNumber *dummyObject = [NSNumber numberWithInteger:123];
return([self initWithObject:dummyObject]);
}
- (id) initWithObject:(NSObject *)paramObject{
self = [super init];
if (self != nil){
/* Keep these values for the main method */
givenObject = paramObject;
}
return(self);
}
- (void) start {
/* If we are cancelled before starting, then
we have to return immediately and generate the required KVO notifications */
if ([self isCancelled]){
/* If this operation *is* cancelled */
/* KVO compliance */
[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
return;
} else {
/* If this operation is *not* cancelled */
/* KVO compliance */
[self willChangeValueForKey:@"isExecuting"];
executing = YES;
/* Call the main method from inside the start method */
[self didChangeValueForKey:@"isExecuting"];
[self main];
}
}
- (void) main {
@try {
@autoreleasepool {
/* Keep a local variable here that must get set to YES whenever we are done with the task */
BOOL taskIsFinished = NO;
/* Create a while loop here that only exists
if the taskIsFinished variable is set to YES or the operation has been cancelled */
while (taskIsFinished == NO && [self isCancelled] == NO){
/* Perform the task here */
NSLog(@"%s", __FUNCTION__);
NSLog(@"Parameter Object = %@", givenObject);
NSLog(@"Main Thread = %@", [NSThread mainThread]);
NSLog(@"Current Thread = %@", [NSThread currentThread]);
/* Very important. This way we can get out of the
loop and we are still complying with the cancellation rules of operations */
taskIsFinished = YES;
}
/* KVO compliance. Generate the required KVO notifications */
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
finished = YES;
executing = NO;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
}
}
@catch (NSException * e) {
NSLog(@"Exception %@", e);
}
}
- (BOOL) isConcurrent{
return YES;
}
- (BOOL) isFinished{
/* Simply return the value */
return finished;
}
- (BOOL) isExecuting{
/* Simply return the value */
return executing;
}
@end
调用测试:
-(void)test6_13_1
{
SimpleOperation *firstOperation;
SimpleOperation *secondOperation;
NSNumber *firstNumber = [NSNumber numberWithInteger:111];
NSNumber *secondNumber = [NSNumber numberWithInteger:222];
firstOperation =[[SimpleOperation alloc] initWithObject:firstNumber];
secondOperation = [[SimpleOperation alloc] initWithObject: secondNumber];
operationQueue = [[NSOperationQueue alloc] init];
/* Add the operations to the queue */
[operationQueue addOperation:firstOperation];
[operationQueue addOperation:secondOperation];
NSLog(@"Main thread is here");
}
输出:
2014-03-12 09:21:00.723 cookbook[385:a0b] Main thread is here
2014-03-12 09:21:00.723 cookbook[385:1403] -[SimpleOperation main]
2014-03-12 09:21:00.723 cookbook[385:360b] -[SimpleOperation main]
2014-03-12 09:21:00.724 cookbook[385:1403] Parameter Object = 222
2014-03-12 09:21:00.724 cookbook[385:360b] Parameter Object = 222
2014-03-12 09:21:00.725 cookbook[385:360b] Main Thread = <NSThread: 0x8978e80>{name = (null), num = 1}
2014-03-12 09:21:00.725 cookbook[385:1403] Main Thread = <NSThread: 0x8978e80>{name = (null), num = 1}
2014-03-12 09:21:00.726 cookbook[385:1403] Current Thread = <NSThread: 0x8e67b40>{name = (null), num = 3}
2014-03-12 09:21:00.726 cookbook[385:360b] Current Thread = <NSThread: 0x8983b80>{name = (null), num = 2}