多线程

《iOS高级开发之多线程编程之三》

2017-04-10  本文已影响30人  皖北威威猫

主队列上的同步异步执行

主队列 异步执行.png 主队列 同步执行.png
分析

从运行结果可以明显看出,程序无法正常执行 被死锁。
接下来看一下锁死的原因:
当程序运行到下面这段代码时
<pre> dispatch_sync(queue, ^{
NSLog(@"hello --- %@",[NSThread currentThread]);
}); </pre>
主线程:如果主线程正在执行行代码,就不调度任务
同步执行: 如果第一个任务没有执行,就等待第一个任务执行完成后,在执行下一个任务。导致程序互相等待,造成死锁。

解决方案

(主队列 同步执行)放入异步执行,解决死锁问题

 dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_queue_t queue1 = dispatch_get_global_queue(0, 0);
//测试执行
NSLog(@"begin");
dispatch_async(queue1, ^{
    for (int i = 0; i <10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"hello---%d %@",i,[NSThread currentThread]);
        });
    }
});
//测试执行
NSLog(@"end");
Snip20170409_6.png

知识拓展

  • 主队列于串行队列的区别

走进NSOperation

  • NSOperation是一个抽象的类
  • NSOperation的子类
  • NSOperationQueue队列
    - (id)initWithTarget:(id)target selector:(SEL)sel object:(nullable id)arg;
注意

默认情况下,调用start方法并不会开一条新线程执行操作,而是在当前线程同步执行操作,只有将一个NSOperation放到NSOperationQueue中,才会异步执行操作

接下来我们来测试一下
 - (void)viewDidLoad {
[super viewDidLoad];
//NSInvocationOperation操作
    //创建操作
  NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(diown) object:nil];
//创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//异步执行
[queue addOperation:operation];
//同步执行

 }
 -(void) diown{
NSLog(@"download --- %@",[NSThread currentThread]);
}
Snip20170409_7.png

可以看出,在子线程中执行的。如果没有将NSOperation放到NSOperationQueue中,将会同步执行,这里不做演示了

    + (instancetype)blockOperationWithBlock:(void (^)(void))block;

*创建addExecutionBlock:方法添加更多操作
- (void)addExecutionBlock:(void (^)(void))block;

注意

只要NSBlockOperation封装的操作 >1 就会执行,异步操作

接下来我们来测试一下
  NSBlockOperation *operation = [[NSBlockOperation alloc]init];
[operation addExecutionBlock:^{
    NSLog(@"----下载图片--1---%@",[NSThread currentThread]);
    
}];
[operation addExecutionBlock:^{
     NSLog(@"----下载图片--2---%@",[NSThread currentThread]);
}];
[operation start];
Snip20170409_8.png
  • NSOperationQueue的作用

NSOperation可以调用start方法来调用任务,但是默认是同步执行。如果将NSOperation添加到NSOperationQueue的队列中,系统会自动,异步执行

  • 添加操作到NSOperationQueue中
  - (void)addOperation:(NSOperation *)op;
  - (void)addOperationWithBlock:(void (^)(void))block ;

下面将演示这两种不同的添加方式

   NSOperationQueue *queue = [[NSOperationQueue alloc]init];
   NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(deom) object:nil];
  [op start];
  [queue addOperation:op];
 - (void) demo{
    NSLog(@"%@",[NSThread currentThread]);
 }
 @interface ViewController ()
 //创建一个全程队列
 @property (nonatomic, strong) NSOperationQueue *queue;
@end
//懒加载
- (NSOperationQueue *)queue{
if (_queue == nil) {
    _queue = [[NSOperationQueue alloc]init];
}
return _queue;
}
[self.queue addOperationWithBlock:^{
   
    NSLog(@"qqq %@",[NSThread currentThread]);

    NSLog(@"下载图片");
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        NSLog(@"回到主线程");
        NSLog(@"%@",[NSThread currentThread]);
    }];
}];
上一篇下一篇

猜你喜欢

热点阅读