点击publisher在Combine中执行两次

问题描述 投票:0回答:2

我不想使用

saveButton.addTarget(:selector:event)
,这就是为什么 我尝试使用来自 CombineCocoa 框架的 Tap 发布者,如下

 saveButton.tapPublisher.sink {  _ in
        print("tap") // tap twice
    }
    .store(in: &subscriptions)

当我点击

saveButton
然后“点击”打印两次。

我也尝试使用 Combine 框架

saveButton.publisher(for: .touchUpInside) 

但有相同的结果。

我的代码在这里

class ArticleVC: UIViewController {
    let saveButton: UIButton = {
        let btn = UIButton()
        btn.setTitle("Save", for: .normal)
        return btn
    }()
    
    var subscriptions: Set<AnyCancellable> = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // add to view
        view.addSubview(saveButton)
        didTapSave()
        saveButton.snp.makeConstraints {
            $0.centerX.centerY.equalToSuperview()
        }
        
        didTapSave()
    }
    
    func didTapSave() {
//        saveButton.tapPublisher.sink(receiveValue: { _ in
//            print("tap")  // twice printed 'tap'
//        })
//        .store(in: &subscriptions)
        /// OR
        saveButton.publisher(for: .touchUpInside).sink { _ in
            print("tap") // twice printed 'tap'
        }
        .store(in: &subscriptions)
    }
}

这是什么原因?

swift combine
2个回答
3
投票

我的猜测是您创建了两次管道。但是您没有显示创建管道的位置,因此这只是一个猜测。 [编辑:在我发布这个答案之后,你在问题中发布了你的代码,我的猜测结果显然是正确的,因为我们现在可以看到你创建了管道两次。]

为了支持这一点,我将展示我所做的:

import UIKit
import Combine
import CombineCocoa

class ViewController: UIViewController {
    @IBOutlet weak var button: UIButton!
    var storage = Set<AnyCancellable>()
    override func viewDidLoad() {
        super.viewDidLoad()
        button.tapPublisher
            .sink { _ in print("tap") }
            .store(in: &storage)
    }
}

这就是所有代码。我运行该项目,点击按钮,我看到“点击”一次。结束了。


0
投票

我的问题是我没有清除

var cancellables = Set<AnyCancellable>()

随后更新发布者变量。我的接收器块还运行一个轮询计时器,因此这引入了一个触发该块两次的竞争条件。

希望这对一些人有帮助。当我停止计时器/会话时,我通过清除

cancellables
解决了这个问题。

cancellables.removeAll()
© www.soinside.com 2019 - 2024. All rights reserved.