Swift Combine:在订阅时只获取第一个值?

Ric*_*ick 1 swift combine

我有一组传统的UIViewControllers 和UIViews,我将 a 传递给Publisher

\n
class MyModel : ObservableObject {\n    @Published var product: Product?\n}\n\n\xe2\x80\xa6\n\nlet someView = SomeView(product: self.model.$product)\n\n\xe2\x80\xa6\n\nclass SomeView : UIView {\n    init(product: Published<Product?>.Publisher) {\n        self.sub = product.sink { prod in <do stuff when it changes> }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

我需要MyModel.product在视图初始化时仅对其中一个属性执行一次操作,而不是每次后续product更新。有没有这样的事情:

\n
    self.pub = product\n        .sinkOnSub { prod in <do when creating this subscription> }\n        .sinkRemaining { prod in <do subsequent times> }\n
Run Code Online (Sandbox Code Playgroud)\n

New*_*Dev 7

您可以创建两个订阅。在第一个处理.first()值中;在第二个单手柄中剩余.dropFirst()

var cancellables: Set<AnyCancellable> = []

product
   .first()
   .sink { prod in 
      // handle first
   }
   .store(in: &cancellables)

product
   .dropFirst()
   .sink { prod in 
      // handle remaining
   }
   .store(in: &cancellables)
Run Code Online (Sandbox Code Playgroud)

或者,如果您必须使用相同的sink,您可以执行 Matt 在评论中建议的操作:使用Scan为每个值附加一个序数:

product
  .scan((0, nil), { (tuple, prod) in 
      (tuple.0 + 1, prod)
  }
  .sink { (n, prod) in
     if n == 1 {
        // handle first
     } else {
        // handle remaining
     }
  }
  .store(in: &cancellables)
Run Code Online (Sandbox Code Playgroud)