NSOperationQueue 多线程

network | | 访问(43)

NSOperationQueue基本用法

// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 2.添加操作到队列中(自动异步执行任务,并发)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片2---%@", [NSThread currentThread]);
}];

[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片3---%@", [NSThread currentThread]);
}];

// 3个操作并发执行

如果想创建一个异步线程,代码如下:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片---%@", [NSThread currentThread]);
}];

高级用法,设置最大线程数:

// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 2.设置最大并发(最多同一时间并发执行3个任务) 1个任务就是串行,大于1就是并行了
queue.maxConcurrentOperationCount = 3;// 下面的9个任务,同一时间解决3个,解决完了再解决3个...

// 3.添加操作到队列中(自动异步执行任务,并发)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片2---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片3---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片4---%@", [NSThread currentThread]);
}];
NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];

[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片5---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片6---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片7---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片8---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片9---%@", [NSThread currentThread]);
}];

高级用法,线程依赖:

 /**
 假设有A、B、C三个操作,要求:
 1. 3个操作都异步执行
 2. 操作C依赖于操作B
 3. 操作B依赖于操作A
 */

// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 2.创建3个操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"A1---%@", [NSThread currentThread]);
}];
// [operationA addExecutionBlock:^{// 给operationA添加一个任务
//     NSLog(@"A2---%@", [NSThread currentThread]);
// }];
//
// [operationA setCompletionBlock:^{// 等operationA完成后,执行下面的代码
//     NSLog(@"AAAAA---%@", [NSThread currentThread]);
// }];

NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"B---%@", [NSThread currentThread]);
}];
NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"C---%@", [NSThread currentThread]);
}];

// 设置依赖
[operationB addDependency:operationA];
[operationC addDependency:operationB];

// 3.添加操作到队列中(自动异步执行任务)
[queue addOperation:operationC];
[queue addOperation:operationA];
[queue addOperation:operationB];

线程通讯(图片下载,子线程下载,回到主线程)

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperationWithBlock:^{
    // 1.异步下载图片
    NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
    NSData *data = [NSData dataWithContentsOfURL:url];
    UIImage *image = [UIImage imageWithData:data];

    // 2.回到主线程,显示图片
    // 2.1 第一种方式
    // [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
    // 2.2 第二种方式
    // dispatch_async(dispatch_get_main_queue(), ^{
    //
    // });
    // 2.2 第三种方式
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        self.imageView.image = image;
    }];
}];

队列的取消、暂停、恢复

// [operation5 cancel] // 单独取消某个线程
// [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复)
// [queue setSuspended:YES]; // 暂停队列中的所有任务
// [queue setSuspended:NO]; // 恢复队列中的所有任务