Ios 在调度获取主队列中使用调度获取全局队列()

Ios 在调度获取主队列中使用调度获取全局队列(),ios,objective-c,multithreading,grand-central-dispatch,Ios,Objective C,Multithreading,Grand Central Dispatch,我已经开始学习“GCD” 我发现,当我们使用FirstWay时,在所有NSLog函数都使用print完成后,将调用alertView 但是当我们使用第二种方式时,将在调用NSLog函数之前调用alertView。 为什么这两种方法运行不同的结果? 这两种方法不是异步方法吗? 我的英语很差,我希望有人能理解我的描述。 谢谢大家! /* *FirstWay */ // dispatch_queue_t globalQueue = dispatch_get_global_queue(DIS

我已经开始学习“GCD”

我发现,当我们使用FirstWay时,在所有
NSLog
函数都使用print完成后,将调用
alertView

但是当我们使用第二种方式时,将在调用
NSLog
函数之前调用
alertView
。 为什么这两种方法运行不同的结果? 这两种方法不是异步方法吗? 我的英语很差,我希望有人能理解我的描述。 谢谢大家!

/* 
 *FirstWay
 */
//    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);        
//    dispatch_async(globalQueue, ^{
//        for (int i = 0; i < 10000 ; i++) {
//            NSLog(@"i = %d", i);
//        }
//        
//        dispatch_async(dispatch_get_main_queue(), ^{
//            NSLog(@"i = %d", i);
//            UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Title " message:@"Message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes", nil];
//            [alertView show];
//        });
//    });

/* 
 *SecondWay
 */
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Title " message:@"Message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes", nil];
        [alertView show];

        dispatch_async(globalQueue, ^{
            for (int i = 0; i < 10000 ; i++) {
                NSLog(@"i = %d", i);
            }
        });
    });
/*
*第一路
*/
//dispatch\u queue\u t globalQueue=dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u DEFAULT,0);
//调度异步(全局队列^{
//对于(int i=0;i<10000;i++){
//NSLog(@“i=%d”,i);
//        }
//        
//dispatch\u async(dispatch\u get\u main\u queue()^{
//NSLog(@“i=%d”,i);
//UIAlertView*alertView=[[UIAlertView alloc]initWithTitle:@“Title”消息:@“message”委托:自取消按钮:@“取消”其他按钮:@“是”,无];
//[警报视图显示];
//        });
//    });
/* 
*第二条路
*/
dispatch\u queue\u t globalQueue=dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u DEFAULT,0);
dispatch\u async(dispatch\u get\u main\u queue()^{
UIAlertView*alertView=[[UIAlertView alloc]initWithTitle:@“Title”消息:@“message”委托:自取消按钮:@“取消”其他按钮:@“是”,无];
[警报视图显示];
调度异步(全局队列^{
对于(int i=0;i<10000;i++){
NSLog(@“i=%d”,i);
}
});
});

在这里,您通过调用dispatch\u async函数向队列提交作业(任务)。dispatch_async的特点是它立即返回,并且提交的块将在后台异步执行。因为与UI相关的任务只在主队列中运行,所以如果您在后台队列中,则需要返回到主队列。您只需调用dispatch\u get\u main\u queue()方法来更新UI

在您的案例中:

在第一种情况下,您将任务提交到全局_队列,而在第二种情况下,您将任务提交到主队列

在第一个队列中,for循环代码从全局_队列执行,内部调度处理程序中的任务被调度到主_队列,在主_队列中更新UI(即显示警报视图)

在第二种情况下,您只需提交到main_队列并更新UI(显示警报),然后将任务分派到全局队列以执行for循环任务

我希望现在它有帮助,如果没有,请随意评论

更多信息:

不要困惑,首先看一下外部调度。你正在调度一些东西在后台工作。你愿意在另一个线程中执行该任务,这样你的主线程就不必等待很长的任务。(如果你的主线程需要很长时间等待某个任务,那么操作系统会杀死你的应用程序,所以GCD可以很容易地让我们摆脱这种情况)。
其次只需将同一外部调度中的代码视为指令(仅逐行代码)。不要与内部调度处理程序混在一起第三个逐行检查这些代码。直到内部分派开始的代码是您希望在后台执行的代码块。嵌套内部分派的原因是来自该后台线程(大多数情况下)在第一种情况下,您这样做是为了在for循环代码完成后显示警报视图。

当您“在后台运行”时,这像伪装吗?与“捕食者”一样,请记住,在使用
dispatch\u get\u global\u queue
时,您的任务运行在给定优先级的任何可用线程上,包括主线程。还请记住,滥用优先级带可能导致优先级不足-例如,安排大量高优先级或默认优先级任务可以防止低优先级任务一直运行。@quellish,这不像在后台伪装。您无法预测的一件事是,后台任务何时开始执行。一个提交的同步是可以估计的,但一个提交的异步是不可能预测的。顺便说一句,在执行后台执行时,您说过的优先级饥饿非常重要。@Bikram。第二种方法可以做我想做的事。但是为什么第一种情况下NSLog方法会阻塞主队列?这是否意味着,如果我向全局_队列提交任务,然后向主_队列提交UI任务(如第一种情况),则主_队列需要等待全局_队列运行结束?