-1

as we know main_queue is a serial queue。There is no real async。

 - (void)someMethod{
   dispatch_async(dispatch_get_main_queue(),^{
    NSLog(@"main_async invoke");
   });
  NSLog(@"method invoke");
 }

the code above "method invoke" will be write before "main_async invoke"。because in main_queue there is no real async. but the code bellow may sai NO:

 - (void)someMethod{
  __block BOOL flag=YES;
      NSBlockOperation *blockOperation = [NSBlockOperation      blockOperationWithBlock:^{
                NSLog(@"blockOperation invoke");
                [NSThread sleepForTimeInterval:4];
                dispatch_async(dispatch_get_main_queue(), ^{
                           NSLog(@"main_async invoke");
                          flag=NO;
                });
      }];
      [blockOperation start];
      while (flag) {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
      }
      NSLog(@"method invoke");
     }

the code above "method invoke" will be write after "main_async invoke" I think it's because of the 'RunLoop'.Is there anyone can explain that's why?

  • What do you mean "real async"? In your first example, the block is executed asynchronously. As you point out, the main queue is a serial queue and as tasks aren't pre-empted, the block won't execute until some time after the current method returns, but it is still asynchronous. Perhaps you mean parallel execution, and no this can't happen on any serial queue. – Paulw11 Mar 01 '17 at 14:22
  • I can understand the first example.my question is why in the second example, ' NSLog(@"main_async invoke")' execute before 'NSLog(@"method invoke")'.In my understanding the block won't execute until some time after the current method returns. In the second example, the block execute before the current method returns. – DoradoIs90 Mar 01 '17 at 15:30
  • Because in the second block you are starting the operation directly. You are not submitting it to an operation queue for execution later. – Paulw11 Mar 01 '17 at 19:53
  • I don't think so.if delete the code in the 'while loop',just change 'while loop' to "while (flag) { NSLog(@"111"); }''.the method will always log "111".that means the 'someMethod' is waitting for flag to be NO by the main_queue async block.but the main_queue async block is waitting for the 'someMethod' returns. so the flag will not be NO. in this way ,i started the operation directly,but the main_queue async block not invoke directly.so I think there is related to RunLoop – DoradoIs90 Mar 02 '17 at 09:50

2 Answers2

0

There is a difference between running async on the main thread, and sync on the main thread. sync basically means, do it right now, async means, do it on the main thread, but it doesn't have to be at this exact moment.

Erik Terwan
  • 2,710
  • 19
  • 28
0

Is there anyone can explain that's why?

Because it is async — asynchronous. That's what asynchronous means. It means "later".

Your code proceeds forwards after the [blockOperation start]; to the end of the method. Only then does the main thread get freed up. So only then does the asynchronous block on the main thread have a chance to come in and get executed.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • It might be useful to explain that the `async` or `sync` in `dispatch_async` applies to the `dispatch_async` call, not the queue itself. The difference being that `dispatch_sync` waits for the block to be executed, where `dispatch_async` doesn't. – David Berry Mar 01 '17 at 17:31