Sto provando a utilizzare il pattern MVVM nel mio nuovo progetto. La prima volta, ho creato tutto il mio modello di visualizzazione per strutturare. Ma quando ho implementato la logica aziendale asincrona come fetchDataFromNetwork con le chiusure, le chiusure catturano il vecchio valore del modello di vista e poi lo aggiornano. Non un nuovo valore del modello di vista.Swift: ViewModel dovrebbe essere una struttura o una classe?
Ecco un codice di prova nel parco giochi.
import Foundation
import XCPlayground
struct ViewModel {
var data: Int = 0
mutating func fetchData(completion:()->()) {
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://stackoverflow.com")!) {
result in
self.data = 10
print("viewModel.data in fetchResponse : \(self.data)")
completion()
XCPlaygroundPage.currentPage.finishExecution()
}.resume()
}
}
class ViewController {
var viewModel: ViewModel = ViewModel() {
didSet {
print("viewModel.data in didSet : \(viewModel.data)")
}
}
func changeViewModelStruct() {
print("viewModel.data before fetch : \(viewModel.data)")
viewModel.fetchData {
print("viewModel.data after fetch : \(self.viewModel.data)")
}
}
}
var c = ViewController()
c.changeViewModelStruct()
Console stampa
viewModel.data before fetch : 0
viewModel.data in didSet : 0
viewModel.data in fetchResponse : 10
viewModel.data after fetch : 0
Il problema è vista Modello in ViewController non ha nuovo valore 10.
Se ho cambiato ViewModel in classe, didSet non chiamato, ma vista Modello in ViewController ha nuovo valore 10.
Quindi non c'è modo di utilizzare struct con chiamata API asincrona @Code? Perché preferisco usare struct che class. – Paul
@Paul Ho modificato il mio post (di nuovo). – Code
Sì, è un cattivo design. :(Dovrei usare la classe per questo caso. Grazie @Code. – Paul