在Cocoa Touch/UIKit上,如何从后台线程检测用户界面的变化



在Cocoa Touch上,如果我们从后台线程更新UI元素,就会发生不好的事情。

问题是,这并不是总是发生的,所以一些轻微的背景UI干扰可能会被忽视一段时间,直到它踢到你的右边牙齿。

是否有一种方法使UIKit运行在一个迂腐的模式,以便一旦有人从后台线程更新一个元素,它崩溃或记录一些东西到控制台?

在进行UI更新之前,您可以检查自己是否在主线程上进行操作。我自己编写了以下宏:

/// 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,它做UI更新。在方法B的开头,我粘贴了BLOCK_UI()宏,如果它没有在UI上运行,它将断言。此外,对于长时间运行的任务,我使用另一个宏。我把这些宏和更多随机的东西放在https://github.com/gradha/ELHASO-iOS-snippets,你可能会发现有用的。

不幸的是,

这些宏在使用时需要遵守规则。处理这种情况的一种更具侵入性的方法可能是通过代理(可能是启动时的搅拌?)包装所有SDK接口对象,该代理断言它们是否在主线程中使用。这些代理/混合只会发生在调试构建或模拟器环境中,以避免阻碍实际发布。我考虑过这样做……但是看起来做起来很痛苦

最新更新