GCD异步方法的行为无法理解 [英] Behavior of GCD async method not understandable

查看:64
本文介绍了GCD异步方法的行为无法理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的iOS应用程序中包含以下内容. 我正在学习GCD.因此,尝试简单的事情.

I have this below in my iOS app. I am learning GCD. so, trying out the simple things.

在这里,此输出使我感到困惑. 为什么总是总是先出现2.组语句,然后才出现1.? 即使我将这两个任务分派给GCD,也要首先分派1.首先设置.因此,1. set和2.set在时间上会重叠,这并不是一项艰巨的任务.仅仅是打印它在什么线程上运行的简单任务.

Here, The output of this is confusing me. Why always the 2. set of statements are coming first and then 1.? Even though I am dispatching the two tasks to GCD, first I am dispatching 1. set first. It is not really a huge task so that 1. set and 2.set will overlap in time. Its just a simple task to print what threads it is running on.

我已经运行了好几次,期望它会在线程环境中产生不同的结果.

I have run it several times expecting that it would give different results as how it happens in threading environment.

请描述.

2. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1}
2. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1}
1. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1}
1. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1}
3. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1}
3. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1}

此处的代码:

void displayAlertView(void *paramContext)
{

    NSLog(@"3. Crnt Thread = %@",[NSThread currentThread]);
    NSLog(@"3. Main thread = %@", [NSThread mainThread]);
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    dispatch_queue_t myQueue = dispatch_get_main_queue();
    AlertViewData *contextData = (AlertViewData *)malloc(sizeof(AlertViewData));
    dispatch_async(myQueue,^(void){
        NSLog(@"1. Crnt Thread = %@",[NSThread currentThread]);
        NSLog(@"1. Main thread = %@", [NSThread mainThread]);
    });
    if(contextData != NULL)
    {
        NSLog(@"2. Crnt Thread = %@",[NSThread currentThread]);
        NSLog(@"2. Main thread = %@", [NSThread mainThread]);

        dispatch_async_f(myQueue, contextData, displayAlertView);
    }

    return YES;
}

推荐答案

"2"语句首先出现是因为在异步块有机会被设置和运行之前,该代码已被执行.这就是dispatch_async的重点.这样的代码将在另一个线程上运行,而当前线程将继续以快乐的方式继续运行.

The "2" statements come first because that code is getting executed before the asynchronous block has had a chance to be setup and run. That's the whole point of dispatch_async. Such code gets run on another thread while the current thread continues on its merry way.

如果您将两个代码块都更新为使用一个循环来记录100条log语句,那么您可能会看到混合了"1"和"2"语句.

If you updated both blocks of code to use a loop that logs 100 logs statements, then you would probably see some mixing of "1" and "2" statements.

但是只有两个日志,它们发生得如此之快,所以在带有"1"日志的块有机会加入之前,"2"日志已经完成.请查看日志中的时间戳以查看.

But with just the two logs, they happen so fast, the "2" logs complete before the block with the "1" logs has had a chance to kick in. Look at the timestamps in the log to see.

更新

以上内容是在myQueue是后台队列的假设下编写的.正如Martin所指出的,这是主要的队列.由于它是主队列,因此答案有很大不同.

The above was written under the assumption that myQueue was a background queue. As Martin pointed out, it's the main queue. Since it is the main queue, the answer is quite a bit different.

由于您正在主队列上进行异步调用,因此所有操作均在同一主线程上完成.每次调用dispatch_async就像将其添加到行末.

Since you are doing asynchronous calls on the main queue, everything is done on the same main thread. Each call to dispatch_async is like adding it to the end of the line.

当前正在运行的代码位于该行的开头.当您为具有"1"日志的块调用dispatch_async时,该块将添加到该行的末尾,并在当前代码完成后运行.然后,将dispatch_async_f称为"3"日志.那些被添加到该行的末尾(在"1"日志之后).

The currently running code is at the head of the line. When you call dispatch_async for the block with the "1" logs, that block is added to the end of the line and will be run when the current code is done. Then you call the dispatch_async_f for the "3" logs. Those get added to the end the line (after the "1" logs).

因此,一旦当前运行循环完成(并且didFinishLaunchingWithOptions`方法返回),则将运行下一行.这是您的"1"日志.完成后,将运行队列中的下一个块(您的"3"个日志).

So once the current runloop completes (and the didFinishLaunchingWithOptions` method returns), then the next bit in line is run. This is your "1" logs. When that is done, the next block in the queue is run (your "3" logs).

这篇关于GCD异步方法的行为无法理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆