逃逸闭包捕获了非逃逸参数'completion' (Swift 5)

5
在我的项目中,我遇到了一种情况,需要使用后台队列来创建 AVPlayerItem (我在 setupTrackModels 函数中创建)。我想在 getTracks 函数中实现它,并且这个方法必须还有一个完成处理程序,我需要在主线程中调用它,但是无论如何我都无法将它们联系起来。我收到编译器错误:Escaping closure captures non-escaping parameter 'completion'。也许有人能告诉我如何做到这一点或者展示另一种方法。
我想要做类似以下的事情:
var content: [URL] = []
var tracks: [TrackModelProtocol] = []

private func getTracks(completion: () -> ()) {
    DispatchQueue.global(qos: .background).async { //Error: Escaping closure captures non-escaping parameter 'completion'
        self.tracks = self.setupTrackModels(content: self.content)
        
        DispatchQueue.main.async { //Error: Escaping closure captures non-escaping parameter 'completion'
            completion()
        }
    }
}

然后我想这样使用该函数:

getTracks {
   tableView.reloadData()
   //or something else
}

我不想在DispatchQueue.main块中使用tableView.reloadData(),因为我多次调用getTracks并且我希望在其完成块中实现不同的逻辑。


2
你需要将 completion 参数标记为 @escaping - Paulw11
就惯例而言,我们现在通常使用Void而不是()作为闭包的返回类型,例如func getTracks(completion: @escaping () -> Void) { ... } - Rob
1个回答

14

使用@escaping

private func getTracks(completion:@escaping () -> ())

你认为在 DispatchQueue 块中使用 completion handler 是一个好的实践吗?还是我必须找到更好的方法? - VyacheslavBakinkskiy
是的,它通常与异步操作一起使用。 - Shehata Gamal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接