Escaping closure captures non-escaping parameter 'completion' (Swift 5)
Asked Answered
W

1

5

In my project, I came across a situation when I need to use the background queue to create an AVPlayerItem (which I create in setupTrackModels function). I'd like do it in getTracks function, and this method must also have a completion handler which I need to call in main thread, but I cannot make them friends in any way. I get compiler error: Escaping closure captures non-escaping parameter 'completion' Maybe someone can tell me how to do this or show another way.

I'd like to do something like this:

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()
        }
    }
}

And then I'd like to use the function like this:

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

I don't want to use tableView.reloadData() in the DispatchQueue.main. block because I call getTracks several times and I want to implement different logic in it's completion block

Wilbur answered 22/10, 2020 at 12:6 Comment(2)
You need to mark the completion parameter as @escapingPathetic
FWIW, as a matter of convention, we now generally use Void rather than () for the closures return type, e.g. func getTracks(completion: @escaping () -> Void) { ... }.Atmolysis
D
15

Use @escaping

private func getTracks(completion:@escaping () -> ())
Delia answered 22/10, 2020 at 12:10 Comment(2)
How do you think, is it a good practice to use a completion handler in the DispatchQueue. block? Or I must find a better way?Wilbur
yes , it's commonly used with an asynchronous operationDelia

© 2022 - 2024 — McMap. All rights reserved.