โ๏ธ 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())
/*
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())
PreviousArgument type 'xxx' does not conform to expected type '_FormatSpecifiable'NextiPad/iPhone is Busy: Fetching debug symbols for ...
Last updated