GCD的基本使用

//
//  ViewController.m
//  gcd队列与函数
//
//  Created by 诠释 on 15/9/3.
//  Copyright (c) 2015年 诠释. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) UIImageView* imageView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //获得主队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();

    //创建一个串行队列
    // 参数1: 队列标记,类似于名字(一般是公司域名反写,可以传nil).
    // 参数2: 标记队列类型,是什么类型就传什么值.
    dispatch_queue_t serialQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
    //创建一个并发队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);

    //获得全局并发队列
    //参数1:队列优先级,一般直接写0,或者写DISPATCH_QUEUE_PRIORITY_DEFAULT(默认)
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//     队列/主队列 + 同步/异步 的使用
    //串行队列+同步  没有开启新线程,串行执行任务
    dispatch_sync(serialQueue, ^{
        
        NSLog(@"我是在串行队列中使用同步执行的函数(任务)");
    });

    //并发队列 + 同步 没有开启新线程,串行执行任务

    dispatch_sync(concurrentQueue, ^{
        
        NSLog(@"我是在并发队列中使用同步执行的函数(任务)");
    });

    //并发队列 + 异步 开启新线程,并发执行任务
    dispatch_async(serialQueue, ^{
        
        NSLog(@"我是在并发队列中使用异步执行的函数(任务)");
    });

    //串行队列 + 异步 开启新线程,串行执行任务
    dispatch_async(serialQueue, ^{
        
        NSLog(@"我是在串行队列中使用异步执行的函数(任务)");
    });

    //主队列 + 同步 不开启新线程,串行执行任务  会卡死当前串行队列
    dispatch_sync(mainQueue, ^{
        
        NSLog(@"我是在主队列中使用同步执行的函数(任务),我会导致主队列堵死,因为主队列执行到我这里,我在等待主队列执行完当前任务(也就是我),然后在执行我本身的任务,可是我需要主队列执行完毕后才能执行我的任务,大家一起完蛋,死循环");
    });

    //主队列 + 异步 不开启新线程,串行执行任务
    dispatch_async(mainQueue, ^{
        
        NSLog(@"我是在主队列中使用异步执行的函数(任务),因为我在主队列,所以我不会开启新的线程,但是我不会堵死主线程,我会等主线程执行完毕当前任务执行完(不包括我),然后在执行我本身的任务");
    });

    
    
//    线程通信 当前环境,在并发队列中使用异步执行下载图片(耗时操作)
    dispatch_async(concurrentQueue, ^{

        NSURL* url = [NSURL URLWithString:@"图片资源路径"];

        NSData* data = [NSData dataWithContentsOfURL:url];

        UIImage* image = [UIImage imageWithData:data];

        //方式1 主线程相对于子线程也是异步
        dispatch_async(dispatch_get_main_queue(), ^{

            NSLog(@"我是在子线程中返回到主线程执行的任务1");

            self.imageView.image = image;
        });

        //waitUntilDone:当前线程是否等待该任务执行完毕
        //方式2 在主线程中执行settingImage方法,
        [self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];

        //方式3  在方式2上充分使用了使用系统方法的一种优化
        //        self.imageView在主线程中调用setImage:方法 == 在主线程[self.imageView setImage:image];
        [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];

        //方式4
        [self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];
    });
    
// 延时调用 //方式1: dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //延时调用内容 }); //方式2: 延时操作执行线程取决于self在哪个线程 [self performSelector:@selector(selector) withObject:nil afterDelay:10]; // 组队列 //创建组队列 dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, serialQueue, ^{ //耗时操作1 }); dispatch_group_async(group, serialQueue, ^{ //耗时操作2 }); //当组队列任务执行完毕后会调用该方法,然后该方法根据参数去哪个队列执行后续操作 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ }); } //方式2调用的方法 在主线程中设置图片 - (void)settingImage:(UIImage*)image { self.imageView.image = image; } @end

 

posted on 2015-09-03 20:12  lizzie8023  阅读(127)  评论(0编辑  收藏  举报