tar*_*rma 11 mutable mvvm ios swift swift-structs
我有一个类(A),它有一个struct变量(S).在这个类的一个函数中,我在struct变量上调用一个mutating函数,这个函数需要一个闭包.此闭包的主体检查struct变量的name属性.
结构的变异函数依次调用某个类(B)的函数.这个类的函数再次关闭.在这个闭包的主体中改变结构,即更改name属性,并调用第一个类提供的闭包.
当我们检查struct的name属性时调用第一个类(A)闭包时,它永远不会被更改.
但是在第2步中,如果我使用结构(C)而不是类B,我会看到内部类A的闭包结构实际上已经改变了.以下是代码:
class NetworkingClass {
func fetchDataOverNetwork(completion:()->()) {
// Fetch Data from netwrok and finally call the closure
completion()
}
}
struct NetworkingStruct {
func fetchDataOverNetwork(completion:()->()) {
// Fetch Data from netwrok and finally call the closure
completion()
}
}
struct ViewModelStruct {
/// Initial value
var data: String = "A"
/// Mutate itself in a closure called from a struct
mutating func changeFromStruct(completion:()->()) {
let networkingStruct = NetworkingStruct()
networkingStruct.fetchDataOverNetwork {
self.data = "B"
completion()
}
}
/// Mutate itself in a closure called from a class
mutating func changeFromClass(completion:()->()) {
let networkingClass = NetworkingClass()
networkingClass.fetchDataOverNetwork {
self.data = "C"
completion()
}
}
}
class ViewController {
var viewModel: ViewModelStruct = ViewModelStruct()
func changeViewModelStruct() {
print(viewModel.data)
/// This never changes self.viewModel inside closure, Why Not?
viewModel.changeFromClass {
print(self.viewModel.data)
}
/// This changes self.viewModel inside/outside closure, Why?
viewModel.changeFromStruct {
print(self.viewModel.data)
}
}
}
var c = ViewController()
c.changeViewModelStruct()
Run Code Online (Sandbox Code Playgroud)
为什么这种行为不同.我认为区别因素应该是我是使用viewModel的结构还是类.但这取决于Networking是一个类还是结构,它独立于任何ViewController或ViewModel.任何人都可以帮我理解这个吗?
这不是一个解决方案,但通过此代码,我们可以看到 ,ViewController's已viewModel.data针对类和结构情况正确设置。不同的是,viewModel.changeFromClass闭包捕获了一个 stale self.viewModel.data。请特别注意,只有 class 的“3 self”打印是错误的。不是包装它的“2 self”和“4 self”印刷品。
class NetworkingClass {
func fetchDataOverNetwork(completion:()->()) {
// Fetch Data from netwrok and finally call the closure
print("\nclass: \(self)")
completion()
}
}
struct NetworkingStruct {
func fetchDataOverNetwork(completion:()->()) {
// Fetch Data from netwrok and finally call the closure
print("\nstruct: \(self)")
completion()
}
}
struct ViewModelStruct {
/// Initial value
var data: String = "A"
/// Mutate itself in a closure called from a struct
mutating func changeFromStruct(completion:()->()) {
let networkingStruct = NetworkingStruct()
networkingStruct.fetchDataOverNetwork {
print("1 \(self)")
self.data = "B"
print("2 \(self)")
completion()
print("4 \(self)")
}
}
/// Mutate itself in a closure called from a class
mutating func changeFromClass(completion:()->()) {
let networkingClass = NetworkingClass()
networkingClass.fetchDataOverNetwork {
print("1 \(self)")
self.data = "C"
print("2 \(self)")
completion()
print("4 \(self)")
}
}
}
class ViewController {
var viewModel: ViewModelStruct = ViewModelStruct()
func changeViewModelStruct() {
print(viewModel.data)
/// This never changes self.viewModel, Why Not?
viewModel.changeFromClass {
print("3 \(self.viewModel)")
print(self.viewModel.data)
}
/// This changes self.viewModel, Why?
viewModel.changeFromStruct {
print("3 \(self.viewModel)")
print(self.viewModel.data)
}
}
}
var c = ViewController()
c.changeViewModelStruct()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3673 次 |
| 最近记录: |