I have this piece of code:
[[FBController sharedController] getUserDetailsWithCompletionBlock:^(NSDictionary *details)
{
// Updating UI elements
}];
I don't understand a thing: when the block
is fired, the secondary thread
is still running. Isn't it more correct that the completion
of a block
should be executed on main thread
automatically?
I know that I am wrong with something and I need a couple of explanations.
The Facebook SDK documentation should give you more details, but in general a well-behaved SDK would call completion blocks on the same thread that the SDK was called from. Any long-running or asynchronous operations that the SDK may perform should operate on a separate thread, usually only visible to the SDK. Whether or not that separate thread is still running or not, is an implementation detail of the SDK - and you shouldn't care about it from the client code perspective.
You can visualise it like this:
Client Code (Main Thread) : [Request]--[Response]-[Continue Thread]-------[Completion Block]
v ^ ^
SDK Code (Main Thread) : [Immediate Operations] |
v |
SDK Code (Private Thread) : [Long Running / Asynchronous Operations]----[Finished]
In the specific example you posted, there's no 'Response' from the getUserDetailsWithCompletionBlock
method, so the thread carries on as usual.
The missing piece to the jigsaw puzzle might be - "How does my completion block get executed on the main thread". Essentially this comes down to the Runloop system. Your main thread isn't actually owned and operated by your code, it's behind the scenes. There's a Main Runloop which periodically looks for things to do. When there's something to do, it operates those somethings on the main thread sequentially. When those somethings have finished, it goes back to looking for something else to do. The SDK basically adds your completion block to the main runloop, so the next time it fires, your block is there waiting to be executed.
Other things that the runloop might be doing are:
etc... etc...