I boiled your question down to this:
1 class Test {
2
3 func asd() {
4 }
5
6 func test() {
7 DispatchQueue.global().async { [self] in
8 DispatchQueue.main.async {
9 self.asd()
10 }
11 DispatchQueue.main.async { [self] in
12 asd()
13 }
14 DispatchQueue.main.sync {
15 self.asd()
16 }
17 DispatchQueue.main.sync { [self] in
18 asd()
^ Call to method 'asd' in closure requires explicit use of 'self' to make capture semantics explicit;
this is an error in Swift 6
19 }
20 }
21 }
22 }
This is an interesting glitch in the matrix. It’s definitely triggered by the context set up by line 7. Without that, you don’t see the warning.
The immediate fix here is to use an explicit self
, as shown by lines 14 through 16. As to why capturing self on line 17 still triggers the warning, I’m not sure. It’s probably worth filing a bug about that. Please post your bug number, just for the record.
Taking a step back, this overall approach is kinda worrying. First, I recommend against using Dispatch global concurrent queues, as explained in Avoid Dispatch Global Concurrent Queues. That’s not triggering this problem — you still see it if you add a serial queue and replace line 7 with self.queue.async
— but if you’re in the habit of using global concurrent queues I recommend that you break that habit.
Second, synchronously dispatching to the main queue is a concern because it can block the current thread for long periods of time.
Taking a further step back, if you’re going to spend time working on code like this, I think you’d be much better off investing in Swift concurrency. While it’s still early days yet, it’s already a much better path forward.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"