# ⛔️ escaping closure captures mutating 'self' parameter

👉  StackOverflow：[What's 'Escaping closure captures mutating 'self' parameter' and how to fix it](https://stackoverflow.com/questions/58327013/swift-5-whats-escaping-closure-captures-mutating-self-parameter-and-how-t)

{% tabs %}
{% tab title="❌  error" %}

```swift
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())
```

{% endtab %}

{% tab title="✅  OK" %}

```swift
/*
 https://stackoverflow.com/a/58327871/5409815
 */

import Combine
import SwiftUI
import PlaygroundSupport

let url: URL = "https://source.unsplash.com/random"

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

// ViewModel
class ViewModel: ObservableObject {
    
    // model
    @Published var image: Image?
    
    // 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()
            
            .assign(to: \.image, on: self)
            .store(in: &subscriptions)
    }
    
    // user intent(s)
    func getImage() {
        taps.send()
    }
    
}

// ContentView
struct ContentView: View {
    
    // view model
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            
            // image
            viewModel.image?
                .resizable().scaledToFit()
                .frame(height: 400).border(Color.black)
            
            // button
            Button(action: {
                self.viewModel.getImage()
            }, label: {
                Text("Tap")
                    .padding().foregroundColor(.white)
                    .background(Color.pink).cornerRadius(12)
            })
            
        }.padding().background(Color.gray)
    }
}

PlaygroundPage.current.setLiveView(ContentView())
```

{% endtab %}

{% tab title="Result" %}
![](https://1830103165-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M5-JmwCZMKh_d7RfBaN%2F-MLh2j_x72WQxPQivCgO%2F-MLh5JGxjjez6oz1IEQ2%2Fcontent%20view%201.png?alt=media\&token=48e3f251-3439-494d-a944-c45ef130a1eb)
{% endtab %}

{% tab title="🌀 套件" %}

* [🌀  URL](https://lochiwei.gitbook.io/ios/swift/scope/framework/built-in-frameworks/foundation/url/url)
  {% endtab %}

{% tab title="👥 相關" %}

* [📦 URLSession.DataTaskPublisher](https://lochiwei.gitbook.io/ios/swift/scope/framework/built-in-frameworks/combine/publishers/urlsession.datataskpublisher)
* [escaping](https://lochiwei.gitbook.io/ios/swift/type/category/basic/closure/escaping "mention")
  {% endtab %}
  {% endtabs %}
