通过 self 更新闭包内的 UI 是一种不好的做法吗?
Posted
技术标签:
【中文标题】通过 self 更新闭包内的 UI 是一种不好的做法吗?【英文标题】:Updating UI inside a closure via self a bad practice? 【发布时间】:2016-11-21 02:31:04 【问题描述】:我对多线程编程还很陌生,到目前为止,我一直在通过 self.myview.setTitle, etc.
更新闭包内的 UI/视图
这是我如何在处理程序/闭包中更新 UI 的示例代码
SFSpeechRecognizer.requestAuthorization (authStatus) in
switch authStatus
case .authorized:
self.recordButton.isEnabled = true
case .denied:
self.recordButton.isEnabled = false
self.recordButton.setTitle("User denied access to speech recognition", for: .disabled)
case .restricted:
self.recordButton.isEnabled = false
self.recordButton.setTitle("Speech recognition is disabled for this device", for: .disabled)
case .notDetermined:
self.recordButton.isEnabled = false
self.recordButton.setTitle("Speech recognition has not yet been authorized", for: .disabled)
default:
break;
这只是我一直在做的一个示例,但我也为其他任务执行此操作,例如从天气 API 下载 json 数据并相应地更新我的 UI 等。
现在我听说这是不好的做法,我希望知道原因。另外,在闭包线程中更新 UI 的正确方法是什么?
【问题讨论】:
【参考方案1】:在闭包内更新 UI 一点也不坏。
但是完全错误并且明确禁止在除主线程之外的任何线程上更新 UI。而且您不知道您的闭包是否在主线程上被调用(并运行)。一般而言,在主线程上调用一个名为异步的完成处理程序是不确定或不可能的。
因此,您应该证明这段代码在主线程上运行,或者通过故意进入主线程来确定更新 UI 之前的线程。
【讨论】:
欣赏信息。我无法证明代码在主线程上运行,因为我不知道。那么,通常不是使用self.someview.
,而是调用 DispatchQueue 来获取主线程并在那里更新 UI,这通常是一个好主意吗?
为了安全起见,是的。这正是我的回答要告诉你的。
换一种说法:您似乎误解了在这种情况下潜在的“不良做法”是什么。我的回答试图为您解决这个问题。这不是句法的事情,而是线程的事情。
感谢您澄清这一点。顺便说一句,这仅适用于 UI 对吗?我的意思是,我可以像在后台线程中一样更新任何其他非视图变量?例如,我有一个实例变量数组,我正在从网上获取一些东西。然后我可以将结果存储在数组中,而无需获取主线程并在那里执行,对吗?为新手问题道歉,但我还是多线程编程实践的新手。
没有关于在哪个线程上更新实例属性的规定,但危险确实潜伏在这里。主线程总是安全的,因为只有一个而且它是串行的。如果您使用另一个线程,您需要知道自己在做什么,否则事情可能会以非常神秘的方式出错。以上是关于通过 self 更新闭包内的 UI 是一种不好的做法吗?的主要内容,如果未能解决你的问题,请参考以下文章