在dispatch_get_main_queue中使用dispatch_get_global_queue()

时间:2014-05-26 05:04:25

标签: ios objective-c multithreading grand-central-dispatch

我已经开始学习" GCD"。

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

但是当我们使用SecondWay时,alertView将在NSLog函数之前调用。 为什么这两种方法会产生不同的结果? 这两种方法可以不是异步方法吗? 我的英语很差,我希望有人能理解我的描述。 谢谢!

/* 
 *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);
            }
        });
    });

1 个答案:

答案 0 :(得分:0)

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

在您的情况下:

在第一种情况下,您将任务提交给global_queue,而在第二种情况下,您已将任务提交到主队列。

在第一个中,for循环代码从global_queue执行,内部分派处理程序内的任务被分派到main_queue,在那里它更新UI(即显示警报视图)。

在第二个中,您只是提交到main_queue并且您正在更新UI(显示警报),然后您将调度到全局队列以执行for循环任务。

我希望现在如果没有帮助,请随时发表评论。

更多信息:

不要混淆,首先只看外部调度。你正在派遣一些东西在后台工作。你愿意在另一个线程中完成这个任务,这样你的主线程就不必等待一些长时间的任务了。(如果你的主线程需要花费很多时间等待一些事情,那么操作系统会杀死你的应用程序,因此GCD可以轻松地将我们带出去。 其次只是将相同外部调度内部的代码视为指令(仅限逐行代码)。不要与内部调度处理程序混合。 第三次逐行浏览。编码到内部调度的开始是你希望在后台执行的代码块。你嵌套内部调度的原因是从那个背景出来在第一种情况下你已经完成了线程(在大多数情况下)你的for循环代码完成后显示警报视图。