В Cocoa Touch/UIKit, как обнаружить изменения в пользовательском интерфейсе из фонового потока?

В Cocoa Touch, если мы обновляем элементы пользовательского интерфейса из фонового потока, происходят плохие вещи.

Проблема в том, что это происходит не постоянно, поэтому какое-то легкое фоновое вмешательство в пользовательский интерфейс может какое-то время оставаться незамеченным, пока оно не ударит вас прямо по зубам.

Есть ли способ заставить UIKit работать в педантичном режиме, чтобы, как только кто-то обновляет элемент из фонового потока, он аварийно завершал работу или записывал что-то в консоль?


person morais    schedule 11.10.2011    source источник


Ответы (1)


Вы можете проверить себя, делаете ли вы что-то в основном потоке или нет, прежде чем выполнять обновления пользовательского интерфейса. Я написал себе следующие макросы:

/// 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!")

Я склонен группировать свой код в методы, где метод A выполняет некоторую обработку, а затем вызывает метод B, который выполняет обновления пользовательского интерфейса. В начале метода B я добавляю макрос BLOCK_UI(), который будет утверждать, если он не запускается в пользовательском интерфейсе. Кроме того, для длительных задач я использую другой макрос. Я разместил эти макросы и другие случайные вещи по адресу https://github.com/gradha/ELHASO-iOS-snippets, которые могут оказаться полезными.

К сожалению, эти макросы требуют дисциплины в их использовании. Более навязчивым способом справиться с такими ситуациями может быть обертка всех объектов интерфейса SDK через прокси (может быть, свистящий при запуске?), который утверждал, если они использовались не в основном потоке. Это проксирование/свизлинг будет происходить только в отладочных сборках или среде симулятора, чтобы не захламлять реальные выпуски. Я думал сделать это ... но похоже, что это сложно сделать правильно.

person Grzegorz Adam Hankiewicz    schedule 11.10.2011