• +86 18940128339
  • 3056844889@qq.com

Category Archive IOS

iOS 多线程

一、iOS中常见的多线程方案

1、pthread
  • 一套通用的多线程API
  • 适用于Unix\Linux\Windows等系统
  • 跨平台、可移植
  • 使用难度大
  • 使用C语言
  • 程序员管理线程生命周期
  • 实际项目中几乎不用
2、NSThread
  • 使用更加面向对象
  • 简单易用、可直接操作线程对象
  • 使用OC语言
  • 程序员管理线程生命周期
  • 实际项目中几乎不用
3、GCD
  • 旨在替代NSThread技术
  • 充分利用设备的多核
  • 使用C语言
  • 自动管理线程生命周期
  • 实际项目中经常使用
4、NSOperation
  • 基于GCD(底层是GCD)
  • 比GCD多了一些简单实用的功能
  • 使用更加面向对象
  • 使用OC语言
  • 自动管理线程生命周期
  • 实际项目中经常使用

二、GCD

1、GCD有两个用来执行任务的函数

  • 同步(sync):只能在当前线程中执行任务,不具备开启新线程的能力,任务立刻马上执行,会阻塞当前线程并等待 Block中的任务执行完毕dispatch函数才会返回,然后当前线程才会继续往下运行。
  • 异步(async):可以在新的线程中执行任务,具备开启线程的能力,但不一定会开启新的线程,dispatch函数会立即返回, 然后Block在后台异步执行,即当前线程会直接往下执行,不会阻塞当前线程。
#pragma mark - 同步执行
- (void)syncQueue {
    NSLog(@"同步主线程开始");
    //创建串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.weixin.globalQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        NSLog(@"同步线程");
    });
    NSLog(@"同步主线程结束");
}

#pragma mark - 异步执行
- (void)asyncQueue {
    NSLog(@"异步主线程开始");
    dispatch_queue_t queue = dispatch_queue_create("com.qq.globalQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"异步线程");
    });
    NSLog(@"异步主线程结束");
}

2、队列

用于存放任务,分为串行队列和并行队列。

  • 串行队列:所有任务会在一条线程中执行(有可能是当前线程也有可能是新开辟的线程),并且一个任务执行完毕后,才开始执行下一个任务。
  • 并行队列:可以开启多条线程并行执行任务(但不一定会开启新的线程),并且当一个任务放到指定线程开始执行时,下一个任务就可以开始执行了
  • 创建队列:

1.串行队列

//创建串行队列
dispatch_queue_t firstQueue = dispatch_queue_create("com.weibo", DISPATCH_QUEUE_SERIAL);

2.并行队列

//创建并行队列
dispatch_queue_t secondQueue = dispatch_queue_create("com.facebook", DISPATCH_QUEUE_CONCURRENT);

3.创建全局默认并发队列

//创建全局默认并发队列
/**
   第一个参数:优先级 也可直接填后面的数字
   #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
   #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默
   #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
   #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台
   第二个参数: 预留参数  0
*/
dispatch_queue_t queue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

4.获取主队列

//获取主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();

5.队列组

dispatch_group_async & dispatch_group_notify

#pragma mark - 队列组
- (void)GCDGroup {
    //创建队列组
    dispatch_group_t group = dispatch_group_create();
    //1.开子线程下载图片
    //创建队列(并发)
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //下载图片1
    dispatch_group_async(group, queue, ^{
        NSURL *url = [NSURL URLWithString:@"http://www.huabian.com/uploadfile/2015/0914/20150914014032274.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        self.image1 = [UIImage imageWithData:data];
        NSLog(@"image1 ==== %@",self.image1);
    });
    
    //下载图片2
    dispatch_group_async(group, queue, ^{
        NSURL *url = [NSURL URLWithString:@"http://img1.3lian.com/img2011/w12/1202/19/d/88.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        self.image2 = [UIImage imageWithData:data];
        NSLog(@"image2 ==== %@",self.image2);
    });
    
    //group中所有任务执行完毕,通知该方法执行
    dispatch_group_notify(group, queue, ^{
        //开启图形上下文
        UIGraphicsBeginImageContext(CGSizeMake(200, 200));
        //画1
        [self.image1 drawInRect:CGRectMake(0, 0, 200, 100)];
        //画2
        [self.image2 drawInRect:CGRectMake(0, 100, 200, 100)];
        //根据图形上下文拿到图片
        UIImage *image =  UIGraphicsGetImageFromCurrentImageContext();
        //关闭上下文
        UIGraphicsEndImageContext();
        //回到主线程刷新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = image;
            NSLog(@"%@--刷新UI",[NSThread currentThread]);
        });
    });
}