首页 > 代码库 > IOS GCD之Block

IOS GCD之Block

  1. GCD延迟执行

#pragma mark - GCD 延迟
/**
 *  dispatch_after
 */
- (void)gcdDelay
{
    NSLog(@"开始时间。。。。。。。%@",[NSDate date]);
    double delaySecond = 2.0;
    dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delaySecond*NSEC_PER_SEC);
    //得到当前的全局队列
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_after(delayInNanoSeconds, concurrentQueue, ^(void){
        NSLog(@"延迟两秒执行......%@",[NSDate date]);
    });
}

C函数执行如下

/**
 *  dispatch_after_f 执行的是一个纯C函数(processSomething)
 */
- (void)gcdDelay_t
{
    NSLog(@"开始时间。。。。。。。%@",[NSDate date]);
    double delaySecond = 2.0;
    dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delaySecond*NSEC_PER_SEC);
    //得到当前的全局队列
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //dispatch_after_f 执行的是一个纯C函数(processSomething)
    dispatch_after_f(delayInNanoSeconds, concurrentQueue, @"GCD", processSomething);
}

void processSomething(void *paramContext){
    NSLog(@"%@",paramContext);
}

2.GCD单例

- (void)gcdSingle
{
    static dispatch_once_t onceTocken;
    
    void (^executedOnlyOnce)(void) = ^{
        static NSUInteger numberOfEntries = 0;
        numberOfEntries++;
        NSLog(@"Executed %lu time(s)", (unsigned long)numberOfEntries);
    };
    
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_once(&onceTocken, ^(void){
        dispatch_async(concurrentQueue, executedOnlyOnce);
    });
    
    dispatch_once(&onceTocken, ^(void){
        dispatch_async(concurrentQueue, executedOnlyOnce);
    });
    
}

可以发现,输出只有一行,虽然我们调用了2次,因为我们传入的dispatch_once_t是相同的,编译器只执行一次。

3.GCD 队列调度

/**
 *  问题:我对每个任务用的是方法dispatch_group_async,是异步的啊。为什么顺序却不变呢?
 *  解答:因为他们都是分配给同一个队列dispatch_get_main_queue() 中的!在一个队列中是串行的啊。所以,还是按照顺序来。
 */
- (void)gcdGroup
{
    // 创建一个调度组
    dispatch_group_t taskGroup = dispatch_group_create();
    // 创建队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
    // 任务1
    // 将Block添加到指定的调度组(taskGroup)中,并且该Block用指定的队列(mainQueue)执行。
    dispatch_group_async(taskGroup, mainQueue, ^{
        [self reloadTableView];
    });
    
    // 任务2
    // 将Block添加到指定的调度组(taskGroup)中,并且该Block用指定的队列(mainQueue)执行。
    dispatch_group_async(taskGroup, mainQueue, ^{
        [self reloadScrollView];
    });
    
    // 任务3
    // 将Block添加到指定的调度组(taskGroup)中,并且该Block用指定的队列(mainQueue)执行。
    dispatch_group_async(taskGroup, mainQueue, ^{
        [self reloadImageView];
    });
    
    dispatch_group_notify(taskGroup, mainQueue, ^{
        [[[UIAlertView alloc] initWithTitle:@"完成" message:@"所有调度完成" delegate:nil cancelButtonTitle:@"完成" otherButtonTitles:nil, nil] show];
    });
    
}


/**
 *  因为dispatch_group_async_f不像dispatch_group_t那样使用Block,可以访问当前类的变量。
 
 * 由于 dispatch_group_async_f 接受 C 函数作为一个代码块来执行,所以,我们要执行reloadTableView方法,reloadScrollView方法,reloadImageView方法,必须有个当前类的引用!!!!!
 * 那么 C 函数必须有一 个引用到 Self,这个 Self 能够调用当前对象的实例方法
 *
 */

/**
 *  C函数的写法
 */

- (void)gcdGroup_c
{
    // 创建一个调度组
    dispatch_group_t taskGroup = dispatch_group_create();
    // 创建队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();

    dispatch_group_async_f(taskGroup, mainQueue, (__bridge void *)self, reloadAllComponents);
    
}

void reloadAllComponents(void *context)
{
    ViewController *self = (__bridge ViewController *)context;
    [self reloadTableView];
    [self reloadScrollView];
    [self reloadImageView];
}

4.自定义队列调度

- (void)gcdCustomeGroup
{
    dispatch_queue_t firstSerialQueue = dispatch_queue_create("com.sinoicity.gcd", NULL);
    
    dispatch_async(firstSerialQueue, ^{
        NSUInteger counter = 0;
        for (counter = 0; counter < 5; counter++){
            NSLog(@"First iteration, counter = %lu", (unsigned long)counter);
        }
        NSLog(@"Current thread = %@", [NSThread currentThread]);
    });
    
    dispatch_async(firstSerialQueue, ^{
        NSUInteger counter = 0;
        for (counter = 0; counter < 5; counter++){
            NSLog(@"Second iteration, counter = %lu", (unsigned long)counter);
        }
        NSLog(@"Current thread = %@", [NSThread currentThread]);
    });

    dispatch_async(firstSerialQueue, ^{
        NSUInteger counter = 0;
        for (counter = 0; counter < 5; counter++){
            NSLog(@"Third iteration, counter = %lu", (unsigned long)counter);
        }
        NSLog(@"Current thread = %@", [NSThread currentThread]);
    });

    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(mainQueue, ^{
        NSLog(@"Main thread = %@", [NSThread mainThread]);
    });
}

注意:我们自定义的队列,往往不会在主队列中执行。而是单独分配一个线程来维护我们所定义的队列。


本文出自 “一念之间” 博客,请务必保留此出处http://5007671.blog.51cto.com/4997671/1590715

IOS GCD之Block