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

发布于 2024-12-09 16:44:46 字数 173 浏览 1 评论 0原文

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

问题是,这种情况不会一直发生,因此一些轻微的后台 UI 干预可能会暂时被忽视,直到它让您大吃一惊。

有没有办法让 UIKit 以迂腐模式运行,以便一旦有人从后台线程更新元素,它就会崩溃或将某些内容记录到控制台?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哭了丶谁疼 2024-12-16 16:44:46

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

不幸的是,这些宏在使用时需要遵守纪律。处理这种情况的一种更具侵入性的方法可能是通过代理包装所有 SDK 接口对象(也许在启动时进行调整?),该代理会断言它们是否不在主线程中使用。这些代理/调配只会在调试版本或模拟器环境中发生,以避免陷入真正的发布困境。我考虑过这样做......但看起来正确地做起来很痛苦。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文