我正在尝试用Combine替换委派模式。
我的应用程序的体系结构是VIPER,所以我需要将接收器订户从一个模块传递到另一个模块。用例是,我有来自模块A(列表(的数据,需要显示给模块B(详细视图(,模块B也可以更新数据,所以我也需要将其返回到模块A。
对于代理,它可以正常工作,但当我使用汇点订阅服务器时,我会遇到一个问题。
当我第一次从模块A转到模块B时,我通过订阅者,然后将其订阅到发布者(从模块B(,它运行良好,模块A中的订阅者从模块B接收所有事件。
但是,当驳回模块B并再次从A路由到B时,订阅者在尝试再次订阅时立即收到一个取消事件:接收订阅:(PublishedSubject(。。。接收取消
我做了一个非常简单的例子来展示正在发生的事情:
模块A:
class ViewController_A: UIViewController {
var subscriber: AnySubscriber<String, Never>!
override func viewDidLoad() {
super.viewDidLoad()
createSubscriber()
}
func createSubscriber() {
let subscriber = Subscribers.Sink<String, Never>(
receiveCompletion: { completion in
print(completion)
}, receiveValue: { value in
print(value)
})
self.subscriber = AnySubscriber(subscriber)
}
func showViewControllerB() {
let viewControllerB = ViewControllerB()
viewControllerB.passSubscriber(AnySubscriber(subscriber))
}
}
模块B:
protocol MyProtocol {
var publisher: Published<String>.Publisher { get }
func passSubscriber(_ subscriber: AnySubscriber<String, Never>)
}
class ViewController_B: UIViewController, MyProtocol {
@Published var word: String = "House"
var publisher: Published<String>.Publisher { $word }
func passSubscriber(_ subscriber: AnySubscriber<String, Never>) {
publisher
.print()
.subscribe(subscriber)
}
func dismiss() {
dismiss(animated: true)
}
}
路由时
let viewControllerA = ViewController_A()
viewControllerA.showViewController_B() // When presenting B for the first time, receiving events here
// Dismiss B here...
viewControllerA.showViewControllerB() // When presenting B again (hence subscribing again), the subscription gets cancelled here without receiving any events/values
我注意到一些有趣的事情。。当我每次路由到模块B时都再次创建订阅者,而不是在viewDidLoad
中只创建一次订阅者时,它似乎工作正常,但我不确定为什么。
这是否意味着一个订阅者一旦订阅了另一个发布者就不能订阅,即使以前的发布者已经不存在了?
我如何才能使它在我的代表团案件中发挥作用?
当我每次路由到模块B时都再次创建订阅者,而不是在viewdidload中只创建一次时,它似乎可以正常工作
正确,因为这正是你应该做的。
已订阅然后被取消/完成的订阅服务器是而非,就像已订阅然后又被取消/已完成的发布服务器是而不是一样。这些都是轻量级对象,创建这些对象是为了方便两个"用户"之间的通信;真实的";端点。当其中一个端点结束时,通信就结束了。
因此,如果你需要一个新的沟通渠道,你只需要创建一个新发布者/订阅者。