NSOperation其实是对GCD进行了面向对象层面的封装。配合使用NSOperation和NSOperationQueue也能实现多线程编程。
配合使用NSOperation和NSOperationQueue实现多线程编程的步骤:
1.先将需要执行的操作封装到一个NSOperation对象中
2.然后将NSOperation对象添加到NSOperationQueue中
3.系统会自动的将NSOperationQueue中的NSOperation取出来
4.将取出的NSOperation封装的操作放到一条新线程中执行
NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类来完成相应的操作。
使用NSOperation子类的方式有3种:
1. NSInvokationOperation
2. NSBlockOperation
3. 自定义子类继承NSOperation,实现内部相应的方法。
在本节中,我先介绍第一点和第二点的使用,下一节用一个例子介绍自定义NSOperation的用法。
NSOperationQueue的作用:
NSOperation可以调用start方法来执行任务,但默认是同步执行的,如果将NSOperation添加到NSOperationQueue中,系统会自动异步执行NSOperation中的操作。
最大并发数的概念
异步任务中,并不是线程开启的越多,执行效率就越高的。有时候有必要控制同时执行的线程个数,这时,我们就可以通过设置NSOperationQueue的maxConcurrentOperationCount属性进行控制。
操作依赖:
NSOperation之间可以设置依赖来保证执行的顺序,比如:操作A执行完毕后,才能执行操作B,可以这样写
[operationB addDependency:operationA];
但注意,操作之间不可以相互依赖。
我下面举了一个例子,将上面所涉及到的概念,进行了汇总:
- (void)viewDidLoad { [super viewDidLoad]; // 回调Operation NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest) object:nil]; NSInvocationOperation *invocationOperation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest2) object:nil]; // block Operation NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"Block Operation(blockOperationWithBlock) -- %@",[NSThread currentThread]); }]; [blockOperation addExecutionBlock:^{ NSLog(@"Block Operation(addExecutionBlock) -- %@",[NSThread currentThread]); }]; // 操作依赖 // 默认Operation相关的操作是异步的,不过通过添加依赖,可以指定相印的同步操作, 下面的代码可以指定invocationOperation在invocationOperation2后面执行~~~ [invocationOperation addDependency:invocationOperation2]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // operation加到队列中会自动异步调用 [queue addOperation:invocationOperation]; [queue addOperation:invocationOperation2]; [queue addOperation:blockOperation]; } - (void)invocationTest { for (int i=0; i<10; i++) { NSLog(@"Invocation Operation -- %@",[NSThread currentThread]); } } - (void)invocationTest2 { for (int i=0; i<10; i++) { NSLog(@"Invocation Operation2 -- %@",[NSThread currentThread]); } }