@Published变量导致崩溃而没有didSet

时间:2019-11-13 18:06:05

标签: swiftui

我有一个ObservableObject视图模型和一个@Published变量,该变量是一个枚举,指示viewModel的状态:

class BatchesViewModel: ObservableObject {
    @Published private var lookupStatus: BatchLookupStatus = .none

    ...

}

enum BatchLookupStatus {
    case none
    case lookingUp(searchText: String)
    case error(errorMessage: String)
    case validated(batch: Batch)
}

我在出现错误或验证时设置状态。在消除错误后,我将状态设置回.none。

一切正常,除了我随机遇到EXC_BAD_ACCESS崩溃。

我想查看发生这种情况时的状态,因此我在设置状态时输入了一条打印语句:

@Published private var lookupStatus: BatchLookupStatus = .none {
    didSet {
        print(_lookupStatus)
    }
}

我注意到,使用该打印语句,崩溃不再发生。实际上,如果我只留下一个空白的didSet,它也可以防止崩溃:

@Published private var lookupStatus: BatchLookupStatus = .none { didSet {} }

一旦我移除didSet,它就会再次崩溃。

世界上正在发生什么?

1 个答案:

答案 0 :(得分:1)

我认为原因不在提供的模型中,因为经过测试,所有结果均符合预期-我的意思是发布刷新流。

这是我所做的模型用法的一个示例:

import SwiftUI
import Combine

class BatchesViewModel: ObservableObject {
    @Published var lookupStatus: BatchLookupStatus = .none
}

enum BatchLookupStatus {
    case none
    case lookingUp(searchText: String)
    case error(errorMessage: String)
}

struct TestPublishCrashed: View {
    @ObservedObject var viewModel = BatchesViewModel()

    var body: some View {
        VStack {
            Button(action: {
                self.viewModel.lookupStatus = .error(errorMessage: "Search failed")
            }) {
                Text("Emulate Error").padding().background(Color.yellow)
            }.padding()

            Button(action: {
                self.viewModel.lookupStatus = .lookingUp(searchText: "hello world")
            }) {
                Text("Emulate Query").padding().background(Color.yellow)
            }.padding()

            status.padding()
        }
    }

    var status: some View {
        switch viewModel.lookupStatus {
            case .none:
                return Text("No status")
            case .error(let error):
                return Text("Got error: \(error)")
            case .lookingUp(let query):
                return Text("Searching: \(query)")
        }
    }
}

struct TestPublishCrashed_Previews: PreviewProvider {
    static var previews: some View {
        TestPublishCrashed()
    }
}