NSOperation
1.先将需要执行的操作封装到一个NSOperation对象中
2.然后将Operation对象添加到NSOperationQueue中
3.系统会自动将NSOperationQueue中的NSOperation取出来
4.将取出的NSOperation封装的操作放到一个新线程中执行
NSOperation是个抽象类,使用其子类的方式有3种
1.NSInvocationOperation
- (void)viewDidLoad
{
[super viewDidLoad];
// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 创建操作
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
// operation直接调用start,是同步执行(在当前线程执行操作)
// [operation start];
// 添加操作到队列中,会自动异步执行
[queue addOperation:operation];
}
- (void)download
{
NSLog(@"download-----%@", [NSThread currentThread]);
}
执行结果为:
download-----{number = 2, name = (null)}
必须要把operation加到队列中,才会新开启线程
2.NSBlockOperation
NSBlockOperation *operation = [[NSBlockOperation alloc] init];
[operation addExecutionBlock:^{
NSLog(@"---下载图片----1---%@", [NSThread currentThread]);
}];
[operation addExecutionBlock:^{
NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
}];
[operation addExecutionBlock:^{
NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
}];
[operation start];
执行结果:
[4189:1352880] ---下载图片----1---{number = 1, name = main}
[4189:1352915] ---下载图片----3---{number = 3, name = (null)}
[4189:1352914] ---下载图片----2---{number = 2, name = (null)}
如果不加到队列中的话,只有在任务数量>1 时候才会异步执行
- (void)viewDidLoad
{
[super viewDidLoad];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---下载图片----1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
}];
// 1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 设置最大并发数
// queue.maxConcurrentOperationCount = 2;
// 设置依赖(操作1完成之后执行操作2,操作2完成之后执行操作3) <strong>注意不能相互依赖</strong>
// [operation2 addDependency:operation1];
// [operation3 addDependency:operation2];
// 2.添加操作到队列中(自动异步执行)
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
// 和上面是一样的意思
[queue addOperationWithBlock:^{
NSLog(@"---下载图片----4---%@", [NSThread currentThread]);
}];
}
执行结果:
[4242:1360620] ---下载图片----1---{number = 2, name = (null)}
[4242:1360619] ---下载图片----2---{number = 4, name = (null)}
[4242:1360630] ---下载图片----4---{number = 3, name = (null)}
[4242:1360623] ---下载图片----3---{number = 5, name = (null)}
都是子线程,而且是并发的.
补充:
[operation1 setCompletionBlock:^{
NSLog(@"当1执行完成后调用这里")
}];
// 取消所有操作
- (void)cancelAllOperations;
// 取消单个操作
- (void)cancel;
// 暂停 YES:暂停所有操作 NO:恢复所有操作
@property (getter=isSuspended) BOOL suspended;
3.自定义子类继承NSOperation,实现内部方法
比如:
@interface MyOperation : NSOperation
@end
@implementation MyOperation
- (void)main {
// 只要创建了MyOperation对象就会走这个方法
// 把要在线程里处理的内容放在这个方法种进行实现
NSInteger a = 0;
for (NSInteger i = 0; i < 60000001; i++) {
a++;
}
NSLog(@"%ld", a);
}
@end
MyOperation *my1 = [[MyOperation alloc] init];
MyOperation *my2 = [[MyOperation alloc] init];
MyOperation *my3 = [[MyOperation alloc] init];
MyOperation *my4 = [[MyOperation alloc] init];
MyOperation *my5 = [[MyOperation alloc] init];
// 把准备好的任务放到队列中
[queue addOperation:my1];
[queue addOperation:my2];
[queue addOperation:my3];
[queue addOperation:my4];
[queue addOperation:my5];
NSOperationQueue是基于GCD的只不过它比GCD更面向对象.