将 dispatch_async 与 self 一起使用
Posted
技术标签:
【中文标题】将 dispatch_async 与 self 一起使用【英文标题】:Using dispatch_async with self 【发布时间】:2014-07-28 08:53:36 【问题描述】:我在将 Objective-C 代码移植到 Swift 时遇到过几次这个问题。假设我有以下代码:
dispatch_async(dispatch_get_main_queue())
self.hostViewController?.view.addSubview(self.commandField)
这将导致错误,在整个dispatch_async
调用下划线,提供:
Could not find member 'addSubview'
我认为这是一个尚未正确实施的错误,因为如果我将 addSubview
调用放在 dispatch_async
块之外,则项目构建良好。最初我认为这可能与在块中捕获self
有关。但是,插入 [unowned self] in
会导致相同的错误,[weak self] in
也会导致同样的错误(在插入适当的 !
展开运算符之后)。
如何让dispatch_async
块在需要捕获self
的Swift 中工作?
【问题讨论】:
【参考方案1】:您应该以非空为条件关闭此操作,而不是在您已经启动它之后对其进行测试:
if let hostView = self.hostViewController?.view
DispatchQueue.main.async
hostView.addSubview(self.commandField)
else
// handle nil hostView
您永远不应该在if let
之外打开可选的包装,或者先对其进行测试。这样做也应该可以解决你的弱自我问题。
【讨论】:
啊,这行得通,谢谢!那么编译器是否抱怨它不能确定性地解开块内的hostController?
?还是这里发生了其他事情?
这是因为表达式self.hostViewController?.view
返回了一个NSView?
类型的对象,不是NSView
。必须始终检查可选链,并且必须允许或强制结果。【参考方案2】:
dispatch_async
语法在 Swift 3 中发生了变化:
DispatchQueue.main.async
hostView.addSubview(self.commandField)
【讨论】:
以上是关于将 dispatch_async 与 self 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
尝试将 dispatch_async 与 cocos2d 函数一起使用时出错
(iOS) dispatch_async() 与 NSOperationQueue
dispatch_async 与 NSOperation 队列