Reputation: 3
I think "end" will be print in for loop, but this is wrong, can you tell me why. This is code:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
for (NSUInteger i = 0; i < 1000; i++) {
dispatch_async(queue, ^{
NSLog(@"i:%lu", (unsigned long)i);
});
}
dispatch_async(queue, ^{
NSLog(@"end:%@", [NSThread currentThread]);
});
Result:
2018-03-22 19:26:33.812371+0800 MyIOSNote[96704:912772] i:990
2018-03-22 19:26:33.812671+0800 MyIOSNote[96704:912801] i:991
2018-03-22 19:26:33.812935+0800 MyIOSNote[96704:912662] i:992
2018-03-22 19:26:33.813295+0800 MyIOSNote[96704:912802] i:993
2018-03-22 19:26:33.813552+0800 MyIOSNote[96704:912766] i:994
2018-03-22 19:26:33.813856+0800 MyIOSNote[96704:912778] i:995
2018-03-22 19:26:33.814299+0800 MyIOSNote[96704:912803] i:996
2018-03-22 19:26:33.814648+0800 MyIOSNote[96704:912779] i:997
2018-03-22 19:26:33.814930+0800 MyIOSNote[96704:912759] i:998
2018-03-22 19:26:33.815361+0800 MyIOSNote[96704:912804] i:999
2018-03-22 19:26:33.815799+0800 MyIOSNote[96704:912805] end:<NSThread: 0x60400027e200>{number = 3, name = (null)}
Upvotes: 0
Views: 46
Reputation: 7552
To combine both of the previous answers, the reason you see end
printed last is because you enqueue serially, but each block executes very quickly. By the time you enqueue the log of end
, all the other blocks have already executed.
Upvotes: 0
Reputation: 318794
Look at the order of execution. You first enqueue 1000 blocks to print a number. Then you enqueue the block to print "end". All of those blocks are enqueued to run asynchronously on the same concurrent background queue. All 1001 calls to dispatch_async
are being done in order, one at a time, on whatever thread this code is being run on which is from a different queue all of the enqueued blocks will be run on.
The concurrent queue will pop each block in the order it was enqueued and run it. Since it is a concurrent queue and since each is to be run asynchronously, in theory, some of them could be a bit out of order. But in general, the output will appear in the same order because each block does exactly the same thing - a simple NSLog
statement.
But the short answer is that "end" is printed last because it was enqueued last, after all of the other blocks have been enqueued.
What may help is to log each call as it is enqueued:
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
for (NSUInteger i = 0; i < 1000; i++) {
NSLog(@"enqueue i: %lu", (unsigned long)i);
dispatch_async(queue, ^{
NSLog(@"run i: %lu", (unsigned long)i);
});
}
NSLog(@"enqueue end");
dispatch_async(queue, ^{
NSLog(@"run end: %@", [NSThread currentThread]);
});
Upvotes: 1
Reputation: 100503
For loop code runs in main Queue (Serial) so the for loop ends then the end statement is printed , if you wrapped the for loop inside the async like this
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (NSUInteger i = 0; i < 1000; i++) {
NSLog(@"i:%lu", (unsigned long)i);
}
});
dispatch_async(queue, ^{
NSLog(@"end:%@", [NSThread currentThread]);
});
you will get this
Upvotes: 0