Swift 合并-订阅服务器在第二次订阅时被自动取消

Swift 合并-订阅服务器在第二次订阅时被自动取消,swift,combine,delegation,viper,Swift,Combine,Delegation,Viper,我试图用Combine替换委托模式 我的应用程序的架构是VIPEr,因此我需要将接收器订户从一个模块传递到另一个模块。用例是我有来自模块A(列表)的数据,需要显示给模块B(详细视图),模块B也可以更新数据,所以我也需要将其返回到模块A 对于学员,它可以正常工作,但当我使用接收器订阅服务器时,我面临一个问题 第一次从模块A转到模块B时,我传递订阅者,然后将其订阅给发布者(从模块B)。它工作正常,模块A中的订阅者从模块B接收所有事件 但是,当解除模块B并再次从A路由到B时,订阅者在再次尝试订阅时立即

我试图用Combine替换委托模式

我的应用程序的架构是VIPEr,因此我需要将接收器订户从一个模块传递到另一个模块。用例是我有来自模块A(列表)的数据,需要显示给模块B(详细视图),模块B也可以更新数据,所以我也需要将其返回到模块A

对于学员,它可以正常工作,但当我使用接收器订阅服务器时,我面临一个问题

第一次从模块A转到模块B时,我传递订阅者,然后将其订阅给发布者(从模块B)。它工作正常,模块A中的订阅者从模块B接收所有事件

但是,当解除模块B并再次从A路由到B时,订阅者在再次尝试订阅时立即收到一个取消事件:接收订阅:(PublishedSubject)。。。接收取消…

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
我做了一个非常简单的例子来说明发生了什么:

模块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))
    }
}
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)
    }
}
我注意到了一些有趣的事情。。当我每次路由到模块B而不是在viewdidload中只创建一次订阅服务器时,它似乎工作正常,但我不确定为什么

这是否意味着订阅者一旦订阅了另一个发布者,就不能再订阅它,即使之前的发布者已经不存在了

我仍然是联合收割机的初学者,但我很想知道如何在我的代表团案例中使其发挥作用

谢谢你的帮助

当我每次路由到模块B而不是在viewdidload中只创建一次订阅服务器时,它似乎工作正常

没错,因为那正是你应该做的

已订阅然后取消/完成的订阅服务器结束,就像已订阅然后取消/完成的发布服务器结束一样。这些是轻量级对象,创建它们是为了促进两个“真实”端点之间的通信。当其中一个端点结束时,通信结束


因此,如果您需要新的通信管道,您只需创建一个新的发布者/订阅者。

您还没有向我们展示更多信息吗?您的showViewControllerB创建一个视图控制器,然后立即将其销毁。顺便说一句,我认为您的分析非常正确。您只能在viewDidLoad中创建订阅服务器一次,并且不能重用订阅服务器。每次A为您的回复生成B.THNK时,您只需重新创建订户!是的,很抱歉,这只是一个测试项目来展示发生了什么,但reals项目是在Viper上制作的,模块不会立即被破坏。哦,我明白了,所以没有办法取消订阅以订阅新的发布者?没有必要。这些是轻量级对象。您正在两个真实对象(视图控制器)之间建立通信管道。当通信因其中一个对象消失而结束时,管道结束。现在您有了一个新的ViewControllerB,创建一个新的管道。谢谢您的回答!那很有趣。我不明白的是,我从来没有取消或完成订阅者,所以当我使用新的发布者再次订阅时,为什么会立即取消?我的印象是,您看到的是第一个管道取消,因为您正试图将其订阅者订阅到另一个管道。但我可能错了。谢谢你@matt。即使我找不到任何与该问题相关的文件,我也会接受你的回答!我将尝试重新创建它无论如何,以确保它不会被取消。谢谢