โ›”๏ธ escaping closure captures mutating 'self' parameter

๐Ÿšง ๆ–ฝๅทฅไธญ

๐Ÿ‘‰ StackOverflow๏ผšWhat's 'Escaping closure captures mutating 'self' parameter' and how to fix it

import Combine
import SwiftUI
import PlaygroundSupport

let url: URL = "https://source.unsplash.com/random"    // ๐ŸŒ€URL

// performs a network request to fetch a random image from Unsplashโ€™s public API
func imagePub() -> AnyPublisher<Image?, Never> {
    URLSession.shared
        .dataTaskPublisher(for: url)
        .map { data, _ in Image(uiImage: UIImage(data: data)!)}
        .print("image")
        .replaceError(with: nil)
        .eraseToAnyPublisher()
}

struct ContentView: View {
    
    @State private var image: Image? = nil
    
    // simulate user taps on a button
    let taps = PassthroughSubject<Void, Never>()
    
    var subscriptions = Set<AnyCancellable>()
    
    init() {
        taps
            // โญ๏ธ map the tap to a new network request
            // โญ๏ธ Publisher<Void, Never> --> Publisher<Publisher<Image?, Never>, Never>
            //    โ€” a publisher of publishers
            .map { _ in imagePub() }
            
            // โญ๏ธ accept only the latest tap
            .switchToLatest()
            
            // โŒ escaping closure captures mutating `self` parameter
            .sink { self.image = $0 }
            
            // โŒ ้›–็„ถไธ‹้ข็š„่ชžๆณ•ๆฒ’ๆœ‰ๅ‡บ็พ้Œฏ่ชค่จŠๆฏ๏ผŒไฝ†ไพ็„ถๆฒ’็”จ
            // .assign(to: \.image, on: self)
            
            .store(in: &subscriptions)
    }
    
    var body: some View {
        VStack {
            image
            Button(action: {
                self.taps.send()
            }, label: {
                Text("Tap").padding().background(Color.pink).cornerRadius(12)
            })
        }.padding().background(Color.gray)
    }
}

PlaygroundPage.current.setLiveView(ContentView())

Last updated