iOS多线程详解

多线程用于后台计算于界面刷新的分离,或将不同的计算任务分配到不同的线程一起开始执行,提高计算效率。

主要介绍一下iOS的GCD:

1. 基本概念:

串行队列:只有一个线程,加入到队列中的操作按添加顺序依次执行。并且还要保证在执行某个任务时,在它前面进入队列的所有任务肯定执行完了。对于每一个不同的串行队列,系统会为这个队列建立唯一的线程来执行代码。

并发队列:这个队列中的任务也是按照先来后到的顺序开始执行,注意是开始,但是它们的执行结束时间是不确定的,取决于每个任务的耗时。对于n个并发队列,GCD不会创建对应的n个线程而是进行适当的优化

同步执行:会阻塞当前线程 sync默认会在当前线程执行(系统优化)

异步执行:异步添加任务

 同步执行异步执行
串行队列当前线程,一个一个执行其他线程,一个一个执行
并行队列当前线程,一个一个执行开很多线程,一起执行
创建队列:
//SWIFT
let  queue = dispatch_queue_create( "testQueue", nil);
let queue = dispatch_queue_create( "seriesQueue", DISPATCH_QUEUE_SERIAL) //串行队列
let queue = dispatch_queue_create( "cocurrentQueue", DISPATCH_QUEUE_CONCURRENT)//并行队列

创建任务:

异步执行:

dispatch_async(<#queue#>, { () -> Void in
      //code here
      println(NSThread.currentThread())
  })

同步执行:

dispatch_sync(<#queue#>, { () -> Void in
      //code here
      println(NSThread.currentThread())
  })


典型错误分析:

界面都是在主线程中,主线程是串行线程。

viewDidAppear方法的代码相当于mainQueue的一个任务(假设任务A), 现在它里面加了个sync的{假设任务B}, 意味着任务B只有等任务A完成才能开始, 但是要完成任务A的话就必须先完成任务B,这样相互等待出现线程阻塞。

因此不能在主线程某个任务中创建其他同步任务。


2. 线程通信:

1 .一个线程传递数据给另一个线程

2 .在一个线程中执行完特定任务后,转到另一个线程继续执行任务

1. GCD 一个线程传递数据搭配另外一个xian'chen

1. `GCD`一个线程传递数据给另一个线程,如:
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    
{   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSLog(@"donwload---%@", [NSThread currentThread]);
        
        // 1.子线程下载图片
        NSURL *url = [NSURL URLWithString:@"http://d.jpg"];
        
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        UIImage *image = [UIImage imageWithData:data];
        
        // 2.回到主线程设置图片
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSLog(@"setting---%@ %@", [NSThread currentThread], image);
            
            [self.button setImage:image forState:UIControlStateNormal];
        });
    });
}
2. NSThread`可以先将自己的当前线程对象注册到某个全局的对象中去,这样相互之间就可以获取对方的线程对象,然后就可以使用下面的方法进行线程间的通信了,由于主线程比较特殊,所以框架直接提供了在主线程执行的方法。
- ( void)performSelectorOnMainThread:(SEL)aSelector withObject:( nullable id)arg waitUntilDone:( BOOL)wait;- ( void)performSelector:(SEL)aSelector onThread:( NSThread *)thr withObject:( nullable id)arg waitUntilDone:( BOOL)wait NS_AVAILABLE( 10_5, 2_0);
用法如下:

//点击屏幕开始执行下载方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self performSelectorInBackground:@selector(download) withObject:nil];
}

//下载图片
- (void)download
{    
    // 1.图片地址
    NSString *urlStr = @"http://d.jpg";
    
    NSURL *url = [NSURL URLWithString:urlStr];
    
    // 2.根据地址下载图片的二进制数据
   
    NSData *data = [NSData dataWithContentsOfURL:url];
    NSLog(@"---end");
    
    // 3.设置图片
    UIImage *image = [UIImage imageWithData:data];
    
    // 4.回到主线程,刷新UI界面(为了线程安全)
    [self performSelectorOnMainThread:@selector(downloadFinished:) withObject:image waitUntilDone:NO];
    
   // [self performSelector:@selector(downloadFinished:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
    
    
}

- (void)downloadFinished:(UIImage *)image
{
    self.imageView.image = image;
    
    NSLog(@"downloadFinished---%@", [NSThread currentThread]);
}
参考:
【1】https://www.jianshu.com/p/fc69da0dce7a
【2】https://www.jianshu.com/p/0b0d9b1f1f19
【3】https://www.jianshu.com/p/51d67a0f3b87
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值