gpt4 book ai didi

ios - 处理可观察序列 RxSwift 上的循环样式事件

转载 作者:行者123 更新时间:2023-12-01 15:40:24 25 4
gpt4 key购买 nike

我想知道处理以下情况的最佳方法,我已经尝试了一种方法,但我遇到了一个事件以循环方式反复调用彼此的问题,因此导致堆栈溢出😂

我有 4 个 observables 如下:-

    let agreeToPrivacyPolicyObservable = BehaviorRelay<Bool>(value: false)
let agreeToTermsObservable = BehaviorRelay<Bool>(value: false)
let agreeToMarketingEmailObservable = BehaviorRelay<Bool>(value: false)
let agreeToAllOptionsObservable = BehaviorRelay<Bool>(value: false)

目标:同步同意所有按钮与个别选项。即,如果同意全部为真/选中,则强制其他选项也被选中,反之亦然。此外,如果检查了所有项目的先前状态并且其中任何一个未被选中,则删除同意所有按钮上的复选标记。

下图可视化了我上面的目标。 Observables

我尝试过的:

Observable.combineLatest(
agreeToPrivacyPolicyObservable,
agreeToTermsObservable,
agreeToMarketingEmailObservable,
agreeToAllOptionsObservable
, resultSelector:{(termsChecked,privacyChecked,marketingChecked,agreeToAllChecked) in
switch (termsChecked,privacyChecked,marketingChecked,agreeToAllChecked) {
case (true, true, true,true):
//All boxes are checked nothing to change.
break
case (false,false,false,false):
//All boxes are unchecked nothing to change.
break
case (true,true,true,false):
// I omitted the `triggeredByAgreeToAll` flag implementation details for clarity
if triggeredByAgreeToAll {
updateIndividualObservables(checked: false)
}else {
agreeToAllOptionsObservable.accept(true)
}
case (false,false,false,true):
if triggeredByAgreeToAll {
updateIndividualObservables(checked: true)
}else {
agreeToAllOptionsObservable.accept(false)
}
default:
if triggeredByAgreeToAll && agreeToAllChecked {
updateIndividualObservables(checked: true)
}else if triggeredByAgreeToAll && agreeToAllChecked == false {
updateIndividualObservables(checked: false)
} else if (termsChecked == false || privacyChecked == false || marketingChecked == false ) {
agreeToAllOptionsObservable.accept(false)
}
}

}

})
.observeOn(MainScheduler.instance)
.subscribe()
.disposed(by: rx.disposeBag)
// Helper function
func updateIndividualObservables(checked: Bool) {
agreeToPrivacyPolicyObservable.accept(checked)
agreeToTermsObservable.accept(checked)
agreeToMarketingEmailObservable.accept(checked)
}

解释:我的尝试给了我 Reentracy anomaly was detected error ,根据我的观察,这是由重复触发的事件引起的。这似乎发生在默认开关案例中(在我上面的解决方案中)。我认为这个解决方案不好,因为我必须检查哪个事件触发了函数执行。

有没有更好的方法或者是否可以将此解决方案重构为易于管理的东西?顺便说一句,请随意忽略我的实现,并建议其他更好的方法(如果有的话)。谢谢!

更新(工作解决方案)

我通过使用@Rugmangathan 的想法成功实现了一个可行的解决方案(在已接受的答案中找到)。所以我把我的解决方案留在这里,以帮助将来遇到同样问题的任何人。这是工作解决方案:-

import Foundation
import RxSwift
import RxRelay


/// This does all the magic of selecting checkboxes.
/// It is shared across any view which uses the license Agreement component.
class LicenseAgreemmentState {

static let shared = LicenseAgreemmentState()
let terms = BehaviorRelay<Bool>(value: false)
let privacy = BehaviorRelay<Bool>(value: false)
let marketing = BehaviorRelay<Bool>(value: false)
let acceptAll = BehaviorRelay<Bool>(value: false)

private let disposeBag = DisposeBag()

func update(termsChecked: Bool? = nil, privacyChecked: Bool? = nil, marketingChecked: Bool? = nil, acceptAllChecked: Bool? = nil) {
if let acceptAllChecked = acceptAllChecked {
// User toggled acceptAll button so change everything to it's value.
acceptAll.accept(acceptAllChecked)
updateIndividualObservables(termsChecked: acceptAllChecked, privacyChecked: acceptAllChecked, marketingChecked: acceptAllChecked)
} else {
// If either of the individual item is missing change acceptAll to false
if termsChecked == nil || privacyChecked == nil || marketingChecked == nil {
acceptAll.accept(false)
}
updateIndividualObservables(termsChecked: termsChecked, privacyChecked: privacyChecked, marketingChecked: marketingChecked)
}

// Deal with the case user triggered select All from individual items and vice-versa.
Observable.combineLatest(terms, privacy, marketing,resultSelector: {(termsChecked,privacyChecked, marketingChecked) in
switch (termsChecked,privacyChecked, marketingChecked) {
case (true, true, true):
self.acceptAll.accept(true)
case (false,false,false):
self.acceptAll.accept(false)
default:
break
}
})
.observeOn(MainScheduler.instance)
.subscribe()
.disposed(by: disposeBag)
}

// MARK: - Helpers
private func updateIndividualObservables(termsChecked: Bool?,privacyChecked: Bool?, marketingChecked:Bool?) {
if let termsChecked = termsChecked {
terms.accept(termsChecked)
}
if let privacyChecked = privacyChecked {
privacy.accept(privacyChecked)
}
if let marketingChecked = marketingChecked {
marketing.accept(marketingChecked)
}
}
}

最佳答案

您的辅助函数 updateIndividualObservables(:) 会在您每次更新时触发一个事件,这反过来会触发您在上面实现的 combineLatest

我建议您改为保留一个 State 对象

struct TermsAndConditionState {
var terms: Bool
var privacy: Bool
var marketing: Bool
var acceptAll: Bool
}

updateIndividualObservables 方法中更改此状态并使用您各自的复选框实现此状态更改

func render(state: TermsAndConditionState) {
if state.acceptAll {
// TODO: update all checkboxes
} else {
// TODO: update individual checkboxes
}
}

关于ios - 处理可观察序列 RxSwift 上的循环样式事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63800707/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com