GCD全解-08-dispatch_group

版权声明:知识版权是属于全人类的! 欢迎评论与转载!!! https://blog.csdn.net/zhuge1127/article/details/82464957

dispatch_group是干什么的?

在处理并发操作的时候,如果是几个block同时并发,我们无法知道最后执行完毕的时候是在哪一个Block中,那么就无法知道在哪一个位置写上结束时的代码?
dispatch_group_async 和 dispatch_group_notify可以实现这个功能。

dispatch_group

dispatch_group将提交到这个group的blocks关联起来,group需要等到所有的Block执行完成之后才能释放内存。

Creates new group with which blocks may be associated.
 * @discussion
 * This function creates a new group with which blocks may be associated.
 * The dispatch group may be used to wait for the completion of the blocks it
 * references. The group object memory is freed with dispatch_release().

dispatch_group_t dispatch_group_create(void);

dispatch_group_async

Submits a block to a dispatch queue and associates the block with the given dispatch group.
 *
 * @discussion
 * Submits a block to a dispatch queue and associates the block with the given
 * dispatch group. The dispatch group may be used to wait for the completion
 * of the blocks it references.
 *
 * @param block
 * The block to perform asynchronously.

void dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);

dispatch_group_wait

Wait synchronously until all the blocks associated with a group have completed or until the specified timeout has elapsed.
 *
 * @discussion
 * This function waits for the completion of the blocks associated with the
 * given dispatch group, and returns after all blocks have completed or when
 * the specified timeout has elapsed.
 *
 * This function will return immediately if there are no blocks associated
 * with the dispatch group (i.e. the group is empty).
 *
 * The result of calling this function from multiple threads simultaneously
 * with the same dispatch group is undefined.
 *
 * After the successful return of this function, the dispatch group is empty.
 * It may either be released with dispatch_release() or re-used for additional
 * blocks. See dispatch_group_async() for more information.
 *

 * @param timeout
 * When to timeout (see dispatch_time). As a convenience, there are the
 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.

long dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);

dispatch_group_notify

Schedule a block to be submitted to a queue when all the blocks associated with a group have completed.
 *
 * @discussion
 * This function schedules a notification block to be submitted to the specified
 * queue once all blocks associated with the dispatch group have completed.
 *
 * If no blocks are associated with the dispatch group (i.e. the group is empty)
 * then the notification block will be submitted immediately.
 *
 * The group will be empty at the time the notification block is submitted to
 * the target queue. The group may either be released with dispatch_release()
 * or reused for additional operations.
 * See dispatch_group_async() for more information.

void dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);

dispatch_group_enter & dispatch_group_leave

Manually indicate a block has entered the group
 *
 * @discussion
 * Calling this function indicates another block has joined the group through
 * a means other than dispatch_group_async(). Calls to this function must be
 * balanced with dispatch_group_leave().

void dispatch_group_enter(dispatch_group_t group);

Manually indicate a block in the group has completed
 *
 * @discussion
 * Calling this function indicates block has completed and left the dispatch
 * group by a means other than dispatch_group_async().

void dispatch_group_leave(dispatch_group_t group);

demo

dispatch_group_notify的应用

dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("com.gcd-group.www",DISPATCH_QUEUE_CONCURRENT);

dispatch_group_async(group, queue, ^{
    for (int i = 0; i < 1000; i++) {
        if (i == 999) {
            NSLog(@"11111111");
        }
    }  
});

dispatch_group_async(group, queue, ^{
    NSLog(@"22222222");
});

dispatch_group_async(group, queue, ^{
    NSLog(@"33333333");
});

dispatch_group_notify(group, queue, ^{
    NSLog(@"done");
});

会在最后输出done,这个地方是处理所有并操作之后的结束位置

dispatch_group_wait的应用

- (NSArray *)fetchTheNetUserData{ 
    //使用GCD创建一个group 组,这个其实不是很好理解,我们可以理解成,创建一个组,然后给这个组添加任务,等到所有组的任务都结束之后在进行一个颁奖典礼,这个就是我们要的效果 
    dispatch_group_t group = dispatch_group_create(); 
    NSMutableArray * array = [NSMutableArray array]; 
    for (int i=0; i<5; i++) { 
        //group 进入一个组 和dispatch_group_leave 这两个必须是成对出现,缺一不可,如果对应不上则会出现线程阻塞, dispatch_group_enter(group); 
        dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
            [array addObject:[NSNumber numberWithInt:i]]; 
            //dispatch_group_leave 离开一个组 ,这个和排毒其实有点类似 
            dispatch_group_leave(group); 
        }); 
    } 
    //dispatch_group_wait 这个函数返回 0则会继续执行,否则一直等待 group 组内的所有成员任务完毕,这个其实也是资源数增加的一个函数,等待当前线程结束 
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 
    NSLog(@"array = %@",array); return array; 
}


#========================================================
- (void)syncAction{
    dispatch_group_t group =dispatch_group_create();
    dispatch_queue_t globalQueue=dispatch_get_global_queue(0, 0);

    dispatch_group_enter(group);

    //模拟多线程耗时操作
    dispatch_group_async(group, globalQueue, ^{
        sleep(3);
        NSLog(@"%@---block1结束。。。",[NSThread currentThread]);
        dispatch_group_leave(group);
    });
    NSLog(@"%@---1结束。。。",[NSThread currentThread]);

    dispatch_group_enter(group);
    //模拟多线程耗时操作
    dispatch_group_async(group, globalQueue, ^{
        sleep(3);
        NSLog(@"%@---block2结束。。。",[NSThread currentThread]);
        dispatch_group_leave(group);
    });
    NSLog(@"%@---2结束。。。",[NSThread currentThread]);

    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"%@---全部结束。。。",[NSThread currentThread]);
    });

}

猜你喜欢

转载自blog.csdn.net/zhuge1127/article/details/82464957