ioscompletion-block

Completion block thread


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.


Solution

  • 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:

    1. UI Updates
    2. Delegate callbacks from UI code
    3. Handling Timers
    4. Touch Handling

    etc... etc...