Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
422 views
in Technique[技术] by (71.8m points)

ios - dispatch_sync always scheduling a block on Main Thread

I am executing a block using dispatch_sync and the block is executed correctly. But this block is executed on the main thread. As per the Apple Doc:

Serial queues (also known as private dispatch queues) execute one task at a time in the order in which they are added to the queue. The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue.

which means (or what I understood) that current process that is being executed will run on a separate thread.

Below is the code that I am using to judge what's going on. It is being called inside NSURLConnection's didReceiveData: delegate method (I know I should not do that inside the didReceiveData: delegate method - but this is just a sample to focus on dispatch_sync). Following are the different ways that I can assume as a proof of my conclusion:

  1. Using dispatch_sync on a Global Concurrent Queue

       dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
            if ([NSThread isMainThread]) {
                NSLog(@"Main Thread");
            }
            else
                NSLog(@"Not on Main Thread");
    
            //Some Process
        });
    

Output -

         Main Thread
         Main Thread 
         Main Thread
         // Main Thread printed till didReceiveData: gets called

  1. Using dispatch_sync on a self created queue using dispatch_queue_create

    // Create queue somewhere else like this
    dispatch_queue_t newQueue = dispatch_queue_create("WriteQueue", DISPATCH_QUEUE_SERIAL);
    
    
       dispatch_sync(newQueue, ^{
    
            if ([NSThread isMainThread]) {
                NSLog(@"Main Thread");
            }
            else
                NSLog(@"Not on Main Thread");
    
            //Some Process
        });
    

Output -

         Main Thread
         Main Thread 
         Main Thread
         // Main Thread printed till didReceiveData: gets called

I am a bit surprised here, block is executed always on the main thread or am I missing something. Because it seems to be going against the Apple Doc I think so. Does anyone know what this is all about?

Update: As per other discussions I understand that dispatch_sync executes a block on the same thread (most of the times), then why apple docs' statements are contradicting in some ways. Why apple says "The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue." Or am I still missing something?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

dispatch_sync() dispatches the block on the same thread, that's normal.

EDIT

Apple's Documentation does not only says this, also says this:

As an optimization, this function invokes the block on the current thread when possible.

As a side note (I know you're talking about the synchronous version, but let's precisate this) I would say that also dispatch_async() may cause multiple blocks to be executed in the same thread.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...