我有一个函数func getValue() -> Bool
,它是从后台线程调用的。这是有意为之的,也是必须的。现在,getValue()
需要在主线程上执行某些操作,在这种情况下,它需要访问UIApplication.shared.canOpenURL
,这必须在主队列上运行。
这是我的当前函数:
func getValue() -> Bool {
guard let url = URL(string: "someurl") else { return false }
return UIApplication.shared.canOpenURL(url)
}
如何将该函数转换为线程安全的函数,即确保它始终在主线程上运行,而不需要:
- 从一开始就从主线程调用函数
- 重构函数以在闭包中返回值
我尝试过这样做:
// This causes a deadlock, see https://dev59.com/TVgQ5IYBdhLWcg3wnVR3#42484670
func getValue() -> Bool {
var flag = false
let group = DispatchGroup()
group.enter()
DispatchQueue.main.async {
if let url = URL(string: "someurl"), UIApplication.shared.canOpenURL(url) {
flag = true
}
group.leave()
}
group.wait()
return flag
}
并且这个:
// This crashes with EXC_BREAKPOINT (SIGTRAP) dispatch_sync called on queue already owned by current thread
func getValue() -> Bool {
return DispatchQueue.main.sync {
guard let url = URL(string: "someurl") else { return false }
return UIApplication.shared.canOpenURL(url)
}
}
但是它们两个都不起作用。有什么想法吗?
DispatchQueue.main.async { if let url = URL(string: "someurl"), UIApplication.shared.canOpenURL(url) { flag = true } } return flag
}` 那么这也行不通,因为调度异步内部的代码永远不会被执行,因为函数已经返回了一个值。 - imas145