Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On Cocoa Touch/UIKit, how to detect changes to the user interface from a background thread?

On Cocoa Touch, if we update UI elements from a background thread, bad stuff happens.

Problem is, it doesn't happen all the time, so some mild background UI meddling might go unnoticed for a while until it kicks your right in the teeth.

Is there a way to make UIKit run in a pedantic mode so that as soon as someone updates an element from a background thread it crashes or logs something to the console?

like image 739
morais Avatar asked Nov 05 '22 13:11

morais


1 Answers

You can check yourself if you are doing stuff on the main thread or not before doing your UI updates. I've written myself the following macros:

/// Stick this in code you want to assert if run on the main UI thread.
#define DONT_BLOCK_UI() \
    NSAssert(![NSThread isMainThread], @"Don't block the UI thread please!")

/// Stick this in code you want to assert if run on a background thread.
#define BLOCK_UI() \
    NSAssert([NSThread isMainThread], @"You aren't running in the UI thread!")

I tend to group my code in methods where method A does some processing and then calls method B, which does the UI updates. At the beginning of method B I stick the BLOCK_UI() macro, which will assert if it is not being run on the UI. Also, for the long running tasks I use the other macro. I've put these macros and more random stuff at https://github.com/gradha/ELHASO-iOS-snippets which you may find useful.

These macros require discipline in using them, unfortunately. A more intrusive way to deal with such situations could be to wrap all the SDK interface objects through a proxy (maybe swizzling at launch?) which asserted if they were used not in the main thread. These proxying/swizzling would happen only in debug builds or simulator environment, to avoid bogging down real releases. I've considered doing this... but looks like a pain to do properly.

like image 93
Grzegorz Adam Hankiewicz Avatar answered Nov 15 '22 13:11

Grzegorz Adam Hankiewicz