你的位置:首页 > 操作系统

[操作系统]IOS中级篇 —— 多线程


GCD 是c语言的框架,不需要手动管理内存
 
是一个面向任务   不是面向线程,不需要管理线程的生命周期
 
GCD 任务/队列 执行函数
任务:Block  任务都封闭在Block中。  —— 线程执行
 
队列:存放任务    FIFO (先进先出的原则)
        GCD中的队列:
                                  串行队列:想要任务按顺序执行
//    创建一个串行队列
    dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
                                  并发队列:想要任务并发执行(同时执行)
//    创建一个并发队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
两个特殊队列
          主队列:主队列中存放的任务最终会交给主线程来执行。
//    获取主队列  不需要创建
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
          全局并发队列:也是并发队列 没有任何区别。 平常开发用非常多。 (不需要管理 程序需要开多少条线程。 会按照当前的设备来自动开线程          
//    获取全局并发队列  不需要创建
//    long identifier  ios8之前 传线程优先级 DISPATCH_QUEUE_PRIORITY_DEFAULT   ios8以后传0 可以兼容之前的版本
//    <#unsigned long flags#> 保留接口 还未用  传 0
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
 
执行函数: 将队列中的任务放到线程中执行
                    同步执行函数:不具备开启新线程的能力。任务中会在当前线程执行。
//      同步
    dispatch_sync(concurrentQueue, ^{
        NSLog(@"下载图片2");
    });
同步函数 + 并发队列 和 + 串行队列 效果是一样的
 
                    异步执行函数:具备开启新线程能力。 是否开启线程不一定。 与队列有关
//    执行函数
//      异步执行
//      dispatch_queue_t queue 队列
//      ^(void)block    任务
    dispatch_async(serialQueue, ^{
        NSLog(@"下载图片");
    });
 
GCD的作用:
     1>将任务添加到队列中
     2>用执行函数执行任务中的任务 
2个执行函数 * 3个队列 
 

同步函数例子

 1 // 同步函数 + 串行队列 2 // 不会开启新线程,任务是在当前线程执行. 3 // 如果当前线程是子线程的话,就是在子线程执行 4 // 任务是按顺序执行的 5 -(void)test1 6 { 7   dispatch_queue_t serialQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); 8   // 同步函数 9   dispatch_sync(serialQueue, ^{10     // 任务11     NSLog(@"下载图片1%@",[NSThread currentThread]);12   });13   // 同步函数14   dispatch_sync(serialQueue, ^{15     // 任务16     NSLog(@"下载图片2%@",[NSThread currentThread]);17   });18   // 同步函数19   dispatch_sync(serialQueue, ^{20     // 任务21     NSLog(@"下载图片3%@",[NSThread currentThread]);22   });23 }24 25 // 同步函数 + 全局并发队列26 // 不会开启新线程,在当前线程执行27 // 如果当前线程是子线程的话,就是在子线程执行28 // 任务按顺序执行29 - (void)test230 {31   dispatch_queue_t queue = dispatch_get_global_queue(0, 0);32   dispatch_sync(queue, ^{33     NSLog(@"下载图片1%@",[NSThread currentThread]);34   });35   dispatch_sync(queue, ^{36     NSLog(@"下载图片2%@",[NSThread currentThread]);37   });38   dispatch_sync(queue, ^{39     NSLog(@"下载图片3%@",[NSThread currentThread]);40   });41 }42 // 对于同步函数 + 串行队列 和 +并发队列 执行效果是一样的.43 // 同步函数 +主队列44 // 主队列中的任务都会交给主线程来执行.45 // 主线程中的任务和主队列中的任务相互等待,无法执行完毕46 - (void)test347 {48   dispatch_sync(dispatch_get_main_queue(), ^{49     NSLog(@"下载图片1%@",[NSThread currentThread]);50   });51   dispatch_sync(dispatch_get_main_queue(), ^{52     NSLog(@"下载图片2%@",[NSThread currentThread]);53   });54   dispatch_sync(dispatch_get_main_queue(), ^{55     NSLog(@"下载图片3%@",[NSThread currentThread]);56   });57   NSLog(@"test3End%@",[NSThread currentThread]);58 59 }

 


异步函数例子  

 
 1 // 异步函数 + 主队列 2   // 不会开启新线程 3   // 任务按顺序执行 4   // 不会卡死主线程 5   dispatch_async(dispatch_get_main_queue(), ^{ 6  7     NSLog(@"下载图片1%@", [NSThread currentThread]); 8   }); 9   // 异步函数 + 主队列10   dispatch_async(dispatch_get_main_queue(), ^{11     NSLog(@"下载图片2%@", [NSThread currentThread]);12   });13   // 异步函数 + 主队列14   dispatch_async(dispatch_get_main_queue(), ^{15     NSLog(@"下载图片3%@", [NSThread currentThread]);16   });17 18 // 异步函数 + 串行队列19 // 开启一条新线程.20 // 一个队列对应一条线程.每一条线程中的任务都是按顺序执行-- 串行执行.21 // 如果创建了多个串行队列,会开启多条线程.22 - (void)test123 {24   dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);25   dispatch_queue_t queue1 = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);26   dispatch_async(queue, ^{27     NSLog(@"下载图片1%@", [NSThread currentThread]);28   });29   dispatch_async(queue1, ^{30     NSLog(@"下载图片2%@", [NSThread currentThread]);31   });32 33   dispatch_async(queue1, ^{34     NSLog(@"下载图片3%@", [NSThread currentThread]);35   });36 37   dispatch_async(queue, ^{38     NSLog(@"下载图片4%@", [NSThread currentThread]);39   });40 } 41 42 // 异步函数 + 全局并发队列43 // 开启一条线程,在子线程中执行任务44 // 根据任务数量,开启多条线程.45 // GCD自动帮我们开启一定数量的线程.46 - (void)test247 {48   dispatch_queue_t queue = dispatch_get_global_queue(0, 0);49   // 异步函数 + 全局并发队列50   dispatch_async(queue, ^{51     NSLog(@"下载图片1%@",[NSThread currentThread]);52   });53   // 异步函数 + 全局并发队列54   dispatch_async(queue, ^{55     NSLog(@"下载图片2%@",[NSThread currentThread]);56   });57 }58 59   // 一次性代码,只会执行一次,能够保证线程安全的.60   // 线程第一次执行完任务之后,其他线程就不会再进来了.61   static dispatch_once_t onceToken;62   dispatch_once(&onceToken, ^{63     NSLog(@"%@",[NSThread currentThread]);64     NSLog(@"一次性代码,只执行一次%@",string);65   });66 67  //队列组的使用68 -(void)groupTest69 {70   __block UIImage *image1,*image2;71   // 创建一个队列组72   dispatch_group_t group = dispatch_group_create();73   // 将我们需要执行的任务放在队列中里面74   // 异步的方法75   dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{76     // 任务177     NSLog(@"renwu 1");78     image1 = [self downloadImageWithUrlString:@"http://e.hiphotos.baidu.com/zhidao/pic/item/203fb80e7bec54e722c5454ebb389b504fc26ab0.jpg"];79   });80   // 再往队列组中添加一个任务81   dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{82     // 任务283     NSLog(@"renwu 2");84     image2 = [self downloadImageWithUrlString:@"http://www.cnwan.com.cn/uploads/allimg/2011-07/01002414-1-10j14.jpg"];  85   });86  // 队列组中的任务都执行完毕以后,会发送一个通知,执行下面的方法87   dispatch_group_notify(group, dispatch_get_main_queue(), ^{88     // 队列组中的任务执行完毕之后的操作89     NSLog(@"renwu over");90    // 合并图片91     self.imageView.image = [self BingImageWith:image1 :image2]; 92   });93 }