簡體   English   中英

如果我嵌套了dispatch_async調用,會發生什么?

[英]What will happen if I have nested dispatch_async calls?

這可能是一個愚蠢的問題,但我需要為自己提出並清楚這一點。

要將塊提交到隊列以執行,請使用函數dispatch_syncdispatch_async 它們都將隊列和塊作為參數。 dispatch_async立即返回,異步運行塊,而dispatch_sync阻止執行,直到提供的塊返回。 以下是一些情況:

情況1

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"this is statement1");

    });
});

情況2

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"this is statement1");

    });
});

情況3

{
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
    dispatch_async(queue, ^{
        [self goDoSomethingLongAndInvolved];
        dispatch_sync(queue, ^{
            NSLog(@"this is statement1");

        });
    });

情況4

{
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
    dispatch_sync(queue, ^{
        [self goDoSomethingLongAndInvolved];
        dispatch_async(queue, ^{
            NSLog(@"this is statement1");

        });
    });

}

並且goDoSomethingLongAndInvolved

-(void)goDoSomethingLongAndInvolved {
    NSLog(@"goDoSomethingLongAndInvolved");
}

我試圖在Xcode中運行它們,但我根本看不出它們的區別。

所以我的問題是:

  1. 這些情況之間的主要區別是什么?
  2. 如果我用dispatch_get_main_queue()替換queue怎么辦?

dispatch_sync語句一直等到它覆蓋的塊完全執行。 dispatch_async立即返回並繼續執行下一行代碼,因此內部的所有內容都是並行發生的。

如果queue是您自己創建的串行隊列,那么:

情況1 - 根塊立即返回。 在里面等待[self go ....],然后轉到dispatch_async,它也會立即返回。

情況2 - 如果queue是一個串行隊列,那么就會有死鎖,因為它會等待自己完成執行。 由於您正在處理異步,因此該塊將並行執行。 (謝謝,@ Ken Thomases)

情況3 - 這里不需要dispatch_sync 它導致死鎖。

情況4 - 等待[self ...],然后立即返回。

如果更換queue與主隊列的話,記得不能dispatch_sync在主隊列,因為它會導致死鎖(不是從主線程也不會出動若感謝@Ken Thomases)。

要更好地理解它,請將您的函數替換為:

-(void)goDoSomethingLongAndInvolved:(NSString *)message {
    for(int i = 0; i < 50; ++i) {
        NSLog(@"%@ -> %d", message, i); 
    }
}

無論是否等待,您都會清楚地看到每次發生的事情。 祝好運。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM