Я немного новичок в Комбинировании и реактивном программировании в целом. Я думаю, что натолкнулся на два разных способа сделать то же самое, но мне интересно, почему я должен выбрать один из других.
У меня есть простая модель, которая хранит и публикует значения, связанные с Apple Смотреть статус. Ниже приведены два разных способа, которые, как мне кажется, я делаю одинаково.
В этом первом подходе я использую отдельный AnyCancellable?
для каждого Publisher
:
class WatchConnectivityModel: ObservableObject {
init() {
activationState = WCSession.default.activationState
isWatchAppInstalled = WCSession.default.isWatchAppInstalled
isComplicationEnabled = WCSession.default.isComplicationEnabled
assignPublishers()
}
@Published var activationState: WCSessionActivationState
@Published var isWatchAppInstalled: Bool
@Published var isComplicationEnabled: Bool
private var activationStateStream: AnyCancellable?
private var isWatchAppInstalledStream: AnyCancellable?
private var isComplicationEnabledStream: AnyCancellable?
private func assignPublishers() {
activationStateStream = WCSession.default
.publisher(for: \.activationState)
.receive(on: RunLoop.main)
.assign(to: \.activationState, on: self)
isWatchAppInstalledStream = WCSession.default
.publisher(for: \.isWatchAppInstalled)
.receive(on: RunLoop.main)
.assign(to: \.isWatchAppInstalled, on: self)
isComplicationEnabledStream = WCSession.default
.publisher(for: \.isComplicationEnabled)
.receive(on: RunLoop.main)
.assign(to: \.isComplicationEnabled, on: self)
}
}
Вот мой второй подход, но вместо отдельных AnyCancellable?
объектов я использую один Set<AnyCancellable>
вместе с .store(in: &self.cancellableSet)
на каждом Publisher
:
class WatchConnectivityModel: ObservableObject {
init() {
activationState = WCSession.default.activationState
isWatchAppInstalled = WCSession.default.isWatchAppInstalled
isComplicationEnabled = WCSession.default.isComplicationEnabled
assignPublishers()
}
@Published var activationState: WCSessionActivationState
@Published var isWatchAppInstalled: Bool
@Published var isComplicationEnabled: Bool
private var cancellableSet: Set<AnyCancellable> = []
private func assignPublishers() {
_ = WCSession.default
.publisher(for: \.activationState)
.receive(on: RunLoop.main)
.assign(to: \.activationState, on: self)
.store(in: &self.cancellableSet)
_ = WCSession.default
.publisher(for: \.isWatchAppInstalled)
.receive(on: RunLoop.main)
.assign(to: \.isWatchAppInstalled, on: self)
.store(in: &self.cancellableSet)
_ = WCSession.default
.publisher(for: \.isComplicationEnabled)
.receive(on: RunLoop.main)
.assign(to: \.isComplicationEnabled, on: self)
.store(in: &self.cancellableSet)
}
}
Я предполагаю, что Первый подход был бы лучше, если бы мне нужно было что-то вручную сделать с одним из трех указанных c потоков, однако в этом случае мне это не нужно. Кроме этого, есть ли что-то, что делает один из этих подходов лучшим выбором, чем другой? Есть ли что-то важное, что я упускаю, когда дело доходит до управления памятью, когда одно происходит поверх другого?
Второе мне кажется немного странным из-за всей части _ =
, потому что это похоже на дополнительный артефакт, который трудно объяснить: почему я все это приписываю ничему? Первый вариант позволяет избежать этой путаницы.