NSInvocationOperation
适用场景
如果你正在对现有的application进行修改,并且application已经有了执行task的object和methods,不妨使用NSInvocationOperation。
For example: you could use an invocation operation to perform a selector that is chosen dynamically based on user input.
代码
- (NSOperation *)taskWithData:(id)data {
NSInvocationOperation *invocationOpt = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(myTaskMethod:) object:data];
return invocationOpt;
}
- (void)myTaskMethod:(id)data {
NSLog(@"currentThread:%@ \n mainThread:%@ \n %@", [NSThread currentThread], [NSThread mainThread], data);
}
放入queue
MyTask *task = [[MyTask alloc] init];
NSOperationQueue *optQueue = [[NSOperationQueue alloc] init];
NSOperation *opt = [task taskWithData:@"event2"];
[optQueue addOperation:opt];
execute manually
MyTask *task = [[MyTask alloc] init];
NSOperation *opt = [task taskWithData:@"event2"];
if (opt.isReady && ![opt isCancelled]) {
if (![opt isConcurrent]) {
[opt start];
} else {
[NSThread detachNewThreadWithBlock:^{
NSLog(@"event3");
}];
}
} else if ([opt isCancelled]) {
[task willChangeValueForKey:@"isFinished"];
[task willChangeValueForKey:@"isExecuting"];
task.finished = YES;
task.executing = NO;
[task didChangeValueForKey:@"isExecuting"];
[task didChangeValueForKey:@"isFinished"];
}
放入queue和start manually区别
把operation放入queue,queue会为operation开辟一个thread,相当于concurrent。
而start manually,operation执行是和调用start的线程一样。即non-concurrent。
2017-01-23 14:20:56.805 ConcurrentTest[93064:1982269] event1
2017-01-23 14:20:56.805 ConcurrentTest[93064:1982313] currentThread:<NSThread: 0x7dd38130>{number = 3, name = (null)}
mainThread:<NSThread: 0x7be33250>{number = 1, name = (null)}
event2
2017-01-23 14:20:56.806 ConcurrentTest[93064:1982269] event3
2017-01-23 14:19:56.238 ConcurrentTest[93032:1981303] event1
2017-01-23 14:19:56.238 ConcurrentTest[93032:1981303] currentThread:<NSThread: 0x79039370>{number = 1, name = main}
mainThread:<NSThread: 0x79039370>{number = 1, name = main}
event2
2017-01-23 14:19:56.239 ConcurrentTest[93032:1981303] event3