Swift Combine публикует дважды

#swift #swiftui #combine

#swift #swiftui #объединить

Вопрос:

 class ObservableFormViewModel: ObservableObject {
  @Published var isSubmitAllowed: Bool = true
  @Published var username: String = ""
  @Published var password: String = ""
  var somethingElse: Int = 10
}

var form = ObservableFormViewModel()

let formSubscription = form.$isSubmitAllowed.sink { _ in
    print("Form changed: (form.isSubmitAllowed) "(form.username)" "(form.password)"")
}


form.isSubmitAllowed = false
form.isSubmitAllowed = false
form.isSubmitAllowed = false
  

Результат таков:

 Form changed: true "" ""
Form changed: true "" ""
Form changed: false "" ""
Form changed: false "" ""
  

Мой вопрос:

  • почему true выводится 2, а false только 2?
  • есть лучший способ удалить дубликат?

Ответ №1:

почему на выходе true получается 2, а false — только 2?

Первый вывод выполняется при создании formSubscription . Следующие три запускаются вашими последовательными form.isSubmitAllowed = false инструкциями.

Обратите внимание, что вы изменяете form.isSubmitAllowed три раза на false , а в выходных данных это происходит только два раза:

 form.isSubmitAllowed = false
form.isSubmitAllowed = false
form.isSubmitAllowed = false

// Form changed: true "" ""
Form changed: true "" ""
Form changed: false "" ""
Form changed: false "" ""
  

Это потому, что вы печатаете не измененное значение, а старое.

Попробуйте это вместо:

 let formSubscription = form.$isSubmitAllowed.sink { isSubmitAllowed in
    print("Form changed: (isSubmitAllowed) "(form.username)" "(form.password)"")
}
  

Это печатает:

 // Form changed: true "" ""
Form changed: false "" ""
Form changed: false "" ""
Form changed: false "" ""
  

Если вы хотите удалить дубликаты, просто используйте removeDuplicates :

 let formSubscription = form.$isSubmitAllowed.removeDuplicates().sink { value in
    print("Form changed: (value) "(form.username)" "(form.password)"")
}

form.isSubmitAllowed = false
form.isSubmitAllowed = false
form.isSubmitAllowed = false
  

Это печатает:

 Form changed: true "" ""
Form changed: false "" ""