ios 观察Singleton时未调用合并`.sink`

42fyovps  于 2023-04-22  发布在  iOS
关注(0)|答案(1)|浏览(109)

当使用合并观察Singleton中的变化时,变化似乎无法识别。我曾尝试将Singleton设置为@ObservableObject并添加self?.objectWillChange.send(),但除此之外,我不知道该怎么做。
This problem看起来很相似,但是我已经在做解决方案建议的事情了。
在我的理解中,这应该每隔3秒在“MODDED”之后打印“CHECK”,但只打印“MODDED”:

class MREViewModel: ObservableObject {
    
    private var cancellables = Set<AnyCancellable>()
    
    @Published var ownUser: MREUser
    
    init() {
        ownUser = MREUserService.shared.ownUser
        setupBindings()
    }
    
    func setupBindings() {
        MREUserService.shared.$ownUser
            .receive(on: DispatchQueue.main)
            .sink { [weak self] user in
                print("CHECK")
                self?.objectWillChange.send()
                self?.ownUser = user
            }
            .store(in: &cancellables)
    }
}

// doesn't work with or without this view that will eventually be used
struct ViewSwiftUI: View {
    
    @ObservedObject var viewModel: MREViewModel
    
    var body: some View {
        Text(viewModel.ownUser.userName)
    }
}

class MREUserService: ObservableObject {
    
    static var shared: MREUserService = MREUserService()
    
    @Published var ownUser = MREUser(userName: "initialised")
    
    var timer: Timer?
    
    init() {
        timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { timer in
            self.objectWillChange.send()
            self.ownUser.userName = "\(Date())"
            print("MODDED: \(self.ownUser.userName)")
        }
    }
}

class MREUser {
    var _id = UUID().uuidString
    var userName: String
    
    init(userName: String) {
        self.userName = userName
    }
}
uhry853o

uhry853o1#

你不能像这样在类之间使用@Published属性,@Published是从视图中访问的。
在这里,您可以使用PassthroughSubject发布更改。
因此在服务类中添加一个subject属性

var userSubject: PassthroughSubject<MREUser, Never>

并使用它来发布更改

self.userSubject.send(self.ownUser)

所以整个服务类现在变成了

class MREUserService {
    static var shared: MREUserService = MREUserService()

    var ownUser = MREUser(userName: "initialised")
    var userSubject: PassthroughSubject<MREUser, Never>
    var timer: Timer?

    init() {
        userSubject = PassthroughSubject()
        timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { timer in
            self.ownUser.userName = "\(Date())"
            self.userSubject.send(self.ownUser)
            print("MODDED: \(self.ownUser.userName)")
        }
    }
}

您需要在视图模型中稍微更改订阅,以便改为订阅这个新属性

MREUserService.shared.userSubject

相关问题