GCD多线程综合

 //回到主线程 为了线程安全 刷新UI 不推荐使用
image 是需要传递的图片
//第一种  YES 参数是等待图片加载完成 再执行后面的方法  
[self performSelectorOnMainThread:@selector(createThread) withObject:image waitUntilDone:YES];
//第二种
     [self performSelector:@selector(createThread) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
//回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"回到主线程");
    });
 
// ****************延时执行**************
 
//1.第一种不会卡主线程
    [self performSelector:@selector(run:) withObject:@"nihao" afterDelay:5];
//2.会卡主主线程
    [NSThread sleepForTimeInterval:5];
//不能控制任务是在哪里执行,这个perform在哪个线程后面的run:方法就在哪里执行
    [self performSelector:@selector(run:) withObject:@"nihao" afterDelay:5];
   
    //可以控制任务执行的位置
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    //3秒后新开子线程,执行任务
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"3秒后开启新线程将任务在子线程中开启");
    });
    //3秒后回到主线程执行任务
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"3秒后执行在主线程");
    });
 
 //(二)队列组的使用  等两个耗时操作完成后 再执行另一个操作 需要创建全局队列对象和队列组对象
 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    __block UIImage *image1 = nil;
    dispatch_group_async(group, queue, ^{
       //下载图片1
        image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/h%3D200/sign=cbca03b6bf12c8fcabf3f1cdcc0292b4/cefc1e178a82b901f3d1b2a5758da9773912ef2c.jpg"]]];
       
    });
    __block UIImage *image2 = nil;
    dispatch_group_async(group, queue, ^{
       //下载图片2
        image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://h.hiphotos.baidu.com/image/pic/item/8718367adab44aedf191a00db61c8701a08bfb78.jpg"]]];

    });
    //两个下载任务都执行完毕后 再执行下面的任务
    dispatch_group_notify(group, queue, ^{
       //合并图片
        //1.开启图形上下文
        UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0);
        //2.画图1
        [image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
        //3.画图2
        [image2 drawInRect:CGRectMake(20, 20, image2.size.width*0.1, image2.size.height*0.1)];
        //4.得到上下文中的图片
        UIImage *currentImage = UIGraphicsGetImageFromCurrentImageContext();
        //5.关闭图形上下文
        UIGraphicsEndImageContext();
       
        //回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
           
            self.image.image = currentImage;
 
        });
    });
 
//线程间通信
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"执行一个耗时操作");
       dispatch_async(dispatch_get_main_queue(), ^{
           NSLog(@"回到主线程刷新UI");
       });
    });
 
 

- (void)asynGlobleQueue
{
    //全局并发队列 只用创建一个全局队列对象 经常使用  多线程
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   
    dispatch_async(queue, ^{
        NSLog(@"下载任务1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载任务2----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载任务3----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载任务4---%@",[NSThread currentThread]);
    });

}

//串行队列 偶尔使用 按顺序执行
- (void)searialQueue
{
    //全局并发队列  经常使用 只开一条线程
    dispatch_queue_t queue = dispatch_queue_create("nihao", NULL);
   
    dispatch_async(queue, ^{
        NSLog(@"下载任务1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载任务2----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载任务3----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下载任务4---%@",[NSThread currentThread]);
    });
    //GCD在ARC环境下不需要release
   
}
 
 
 
posted @ 2016-05-05 01:08  aRenOuBa  阅读(319)  评论(0编辑  收藏  举报