Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在SwiftUI中继承ObserveObject时未触发视图刷新_Ios_Swift_Swiftui_Combine - Fatal编程技术网

Ios 在SwiftUI中继承ObserveObject时未触发视图刷新

Ios 在SwiftUI中继承ObserveObject时未触发视图刷新,ios,swift,swiftui,combine,Ios,Swift,Swiftui,Combine,ContentView2视图在model.value更改时不会刷新,如果model直接符合observeObject而不是继承SuperModel,则其工作正常 class SuperModel: ObservableObject { } class Model: SuperModel { @Published var value = "" } struct ContentView2: View { @ObservedObject var model = Model()

ContentView2
视图在
model.value
更改时不会刷新,如果
model
直接符合
observeObject
而不是继承
SuperModel
,则其工作正常

class SuperModel: ObservableObject {

}

class Model: SuperModel {
    @Published var value = ""
}

struct ContentView2: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
        }

    }
}

使用ObjectWillChange解决指定的问题

以下是工作代码:

import SwiftUI

class SuperModel: ObservableObject {

}

class Model: SuperModel {
    var value: String = "" {
        willSet { self.objectWillChange.send() }
    }
}

struct ContentView: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text("Model Value1: \(model.value)")
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
            Text("Model Value2: \(model.value)")
        }
    }
}

这看起来真的很严重

如我所见,
已更改,并按预期保留新值,但
动态属性
功能不起作用

以下变体适用于我(Xcode 11.2/iOS 13.2)


下面是您的示例的工作变体。要确保能够工作,不仅需要链接发布者,还需要至少一个已发布属性。在某些情况下,它可能会有所帮助

import SwiftUI

class SuperModel: ObservableObject {
    // this is workaround but not real trouble.
    // without any value in supermodel there is no real usage of SuperModel at all
    @Published var superFlag = false
}

class Model: SuperModel {
    @Published var value = ""
    override init() {
        super.init()
        _ = self.objectWillChange.append(super.objectWillChange)
    }
}

struct ContentView: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
        }

    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
将代码更改为

var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
            Text(model.superFlag.description)
            Button("change super flag") {
                self.model.superFlag.toggle()
            }
        }

    }
你可以同时看到如何使用你的超级模特


那么使用继承有什么意义呢?我可以直接用超模做我的模特。实际上,SuperModel有很多发布者,Model应该会添加更多的发布者,您可以继承类对象。然而,ObservieObject是一个协议。根据()文档,ObserveObject合成已发布的属性。你们不能继承这个行为。那个么,我怎样才能使模型符合ObserveObject协议呢
class Model:SuperModel,ObservableObject{}
被禁止“模型”与协议“ObservableObject”的冗余一致性”我在上面编辑了我的答案,解决了您的继承性和ObservableObject一致性问题。您的变体不适用于我,您使用哪个Xcode进行测试?值得向苹果报告,请提交反馈。@Asperi如果至少有一个已发布的属性是supermodel的一部分,则解决方案存在。请看我的回答问题在于,您需要对模型中的每个已发布属性执行相同的操作。看看我的答案中如何解决它。
class SuperModel {
}

class Model: SuperModel, ObservableObject {
    @Published var value = ""
}
import SwiftUI

class SuperModel: ObservableObject {
    // this is workaround but not real trouble.
    // without any value in supermodel there is no real usage of SuperModel at all
    @Published var superFlag = false
}

class Model: SuperModel {
    @Published var value = ""
    override init() {
        super.init()
        _ = self.objectWillChange.append(super.objectWillChange)
    }
}

struct ContentView: View {

    @ObservedObject var model = Model()

    var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
        }

    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
var body: some View {
        VStack {
            Text(model.value)
            Button("change value") {
                self.model.value = "\(Int.random(in: 1...10))"
            }
            Text(model.superFlag.description)
            Button("change super flag") {
                self.model.superFlag.toggle()
            }
        }

    }