Ios 在哪里调用GCD机制?

Ios 在哪里调用GCD机制?,ios,grand-central-dispatch,Ios,Grand Central Dispatch,我跟着,但我不明白: 首次实施 - (void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1 __block NSError *error; disp

我跟着,但我不明白:

首次实施

    - (void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1

        __block NSError *error;
        dispatch_group_t downloadGroup = dispatch_group_create(); // 2

        for (NSInteger i = 0; i < 3; i++) {
            NSURL *url;
            switch (i) {
                case 0:
                    url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];
                    break;
                case 1:
                    url = [NSURL URLWithString:kSuccessKidURLString];
                    break;
                case 2:
                    url = [NSURL URLWithString:kLotsOfFacesURLString];
                    break;
                default:
                    break;
            }

            dispatch_group_enter(downloadGroup); // 3
            Photo *photo = [[Photo alloc] initwithURL:url
                                  withCompletionBlock:^(UIImage *image, NSError *_error) {
                                      if (_error) {
                                          error = _error;
                                      }
                                      dispatch_group_leave(downloadGroup); // 4
                                  }];

            [[PhotoManager sharedManager] addPhoto:photo];
        }
        dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER); // 5
        dispatch_async(dispatch_get_main_queue(), ^{ // 6
            if (completionBlock) { // 7
                completionBlock(error);
            }
        });
    });
}
-(void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock
{
调度异步(调度获取全局队列(调度队列优先级高,0),^{//1
__块N错误*错误;
dispatch_group_t downloadGroup=dispatch_group_create();//2
对于(NSInteger i=0;i<3;i++){
NSURL*url;
开关(一){
案例0:
url=[NSURL URLWithString:kOverlyAttachedGirlfriendURLString];
打破
案例1:
url=[NSURL URLWithString:kSuccessKidURLString];
打破
案例2:
url=[NSURL URLWithString:kLotsOfFacesURLString];
打破
违约:
打破
}
调度组输入(下载组);//3
Photo*Photo=[[Photo alloc]initwithURL:url
withCompletionBlock:^(UIImage*图像,N错误*\U错误){
如果(_错误){
错误=_错误;
}
调度组离开(下载组);//4
}];
[[PhotoManager sharedManager]添加照片:照片];
}
调度组等待(下载组,调度时间永远);/5
dispatch\u async(dispatch\u get\u main\u queue(),^{//6
if(completionBlock){//7
完成块(错误);
}
});
});
}
第二次执行:

    - (void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock
{
    // 1
    __block NSError *error;
    dispatch_group_t downloadGroup = dispatch_group_create(); 

    for (NSInteger i = 0; i < 3; i++) {
        NSURL *url;
        switch (i) {
            case 0:
                url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];
                break;
            case 1:
                url = [NSURL URLWithString:kSuccessKidURLString];
                break;
            case 2:
                url = [NSURL URLWithString:kLotsOfFacesURLString];
                break;
            default:
                break;
        }

        dispatch_group_enter(downloadGroup); // 2
        Photo *photo = [[Photo alloc] initwithURL:url
                              withCompletionBlock:^(UIImage *image, NSError *_error) {
                                  if (_error) {
                                      error = _error;
                                  }
                                  dispatch_group_leave(downloadGroup); // 3
                              }];

        [[PhotoManager sharedManager] addPhoto:photo];
    }

    dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{ // 4
        if (completionBlock) {
            completionBlock(error);
        }
    });
}
-(void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock
{
// 1
__块N错误*错误;
dispatch_group_t downloadGroup=dispatch_group_create();
对于(NSInteger i=0;i<3;i++){
NSURL*url;
开关(一){
案例0:
url=[NSURL URLWithString:kOverlyAttachedGirlfriendURLString];
打破
案例1:
url=[NSURL URLWithString:kSuccessKidURLString];
打破
案例2:
url=[NSURL URLWithString:kLotsOfFacesURLString];
打破
违约:
打破
}
调度组输入(下载组);//2
Photo*Photo=[[Photo alloc]initwithURL:url
withCompletionBlock:^(UIImage*图像,N错误*\U错误){
如果(_错误){
错误=_错误;
}
调度组离开(下载组);//3
}];
[[PhotoManager sharedManager]添加照片:照片];
}
调度组通知(下载组,调度获取主队列(),^{//4
if(完成块){
完成块(错误);
}
});
}
在第一个实现中,相关代码被
dispatch\u async
包围,一切都非常清晰

但是,第二次实施还不清楚!我不明白,
GCD
机制是如何在进入和离开通知之外发挥作用的


提前10倍

第一种方法是异步方法。您可以从任何线程调用它,包括主线程。它将在后台线程中执行操作,完成后,它将在主线程上调度回调块。对该方法的调用将立即返回,回调将在以后多次调用


第二种方法是阻塞方法。在下载照片并调用回调方法之前,该方法不会完成。这个方法绝不能从主线程调用,只能从后台线程调用

第一个实现从开始运行后台线程

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
所以整个函数都在那里运行。但该后台线程最终在这一行被阻止(它等待下载所有照片):

这一切都很好,因为您没有阻塞主线程。但它的实现有点笨拙,因为

  • 你阻塞了一个你真的不需要的线程
  • 整个函数的
    dispatch\u async
    看起来有点难看
因此,第二个实现有两个好处:

  • 它并没有那么“难看”,可读性更高(因为您去掉了
    调度异步(dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u HIGH,0),^{}
  • 并且没有块,因为
    dispatch\u group\u notify
    充当异步完成块

Ok@gnasher729 TNX。你认为ray打算从后台线程调用此方法吗?为什么以及如何得出结论?我认为@gnasher729打算通过block从后台线程调用第二个实现来阻塞方法。你误解了这一点。
 dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER);