Наблюдение нескольких опубликованных изменений переменных внутри ObservableObject

#ios #swift #swiftui

Вопрос:

У меня есть ObservableObject приложение, содержащее несколько опубликованных переменных для обработки состояния моего приложения. Всякий раз, когда меняется одна из этих опубликованных переменных, я хочу вызвать функцию внутри моей ObservableObject . Как лучше всего это сделать?

 class AppModelController: ObservableObject {

    @Published var a: String = "R"
    @Published var b: CGFloat = 0.0
    @Published var c: CGFloat = 0.9
    
    // Call this function whenever a, b or c change
    func check() -> Bool {

    }
}
 

Ответ №1:

Самое простое, что вы можете сделать, — это слушать objectWillChange . Загвоздка в том, что он вызывается до обновления объекта. Вы можете использовать .receive(on: RunLoop.main) для получения обновлений в следующем цикле, которые будут отражать измененные значения:

 import Combine

class AppModelController: ObservableObject {

    @Published var a: String = "R"
    @Published var b: CGFloat = 0.0
    @Published var c: CGFloat = 0.9
    
    private var cancellable : AnyCancellable?
    
    init() {
        cancellable = self.objectWillChange
        .receive(on: RunLoop.main)
        .sink { newValue in
            let _ = self.check()
        }
    }
    
    // Call this function whenever a, b or c change
    func check() -> Bool {
        return true
    }
}
 

Комментарии:

1. Спасибо, @jnpdx. Я чувствую, что схема, которой я следую, неверна. Есть ли какой-либо другой способ достичь того же результата, но более «стандартным» способом, или это то, что есть? 🙂

2. Это именно то, что это (или didSet метод в другом ответе). Лично мне нравится этот метод, так как, если бы я добавил/удалил свойство, все это все равно работало бы.

3. @Хамид, ты не поддержал ни один из ответов здесь. Нашли ли вы какой-либо ответ полезным в любом случае?

4. Я проверю оба ответа сегодня или завтра, а затем вернусь сюда. Спасибо за вашу помощь.

Ответ №2:

Вы можете использовать didSet, как этот код:

 class AppModelController: ObservableObject {

    @Published var a: String = "R" { didSet(oldValue) { if (a != oldValue) { check() } } }
    @Published var b: CGFloat = 0.0 { didSet(oldValue) { if (b != oldValue) { check() } } }
    @Published var c: CGFloat = 0.9 { didSet(oldValue) { if (c != oldValue) { check() } } }
    

    func check() {
        
        // Some Work!

    }
}