Когда я портирую некоторый код Objective C на Swift, я пытаюсь лучше понять новую инфраструктуру Combine
и то, как я могу использовать ее для воссоздания общего шаблона проектирования.
В этом случае шаблон проектирования - это отдельный объект (менеджер, служба и т. Д.), В котором любое количество «клиентов» может зарегистрироваться в качестве делегата для получения обратных вызовов. Это основной 1: Многие паттерны с использованием делегатов.
Combine
выглядит идеально для этого, но пример кода немного тонкий. Ниже приведен рабочий пример, но я не уверен, что он правильный или используется по назначению. В частности, мне интересно узнать о ссылочных циклах между объектами.
class Service {
let tweets = PassthroughSubject<String, Never>()
func start() {
// Simulate the need send to send updates.
DispatchQueue.global(qos: .utility).async {
while true {
self.sendTweet()
usleep(100000)
}
}
}
func sendTweet() {
tweets.send("Message \(Date().timeIntervalSince1970)")
}
}
class Client : Subscriber {
typealias Input = String
typealias Failure = Never
let service:Service
var subscription:Subscription?
init(service:Service) {
self.service = service
// Is this a retain cycle?
// Is this thread-safe?
self.service.tweets.subscribe(self)
}
func receive(subscription: Subscription) {
print("Received subscription: \(subscription)")
self.subscription = subscription
self.subscription?.request(.unlimited)
}
func receive(_ input: String) -> Subscribers.Demand {
print("Received tweet: \(input)")
return .unlimited
}
func receive(completion: Subscribers.Completion<Never>) {
print("Received completion")
}
}
// Dependency injection is used a lot throughout the
// application in a similar fashion to this:
let service = Service()
let client = Client(service:service)
// In the real world, the service is started when
// the application is launched and clients come-and-go.
service.start()
Вывод:
Received subscription: PassthroughSubject
Received tweet: Message 1560371698.300811
Received tweet: Message 1560371698.4087949
Received tweet: Message 1560371698.578027
...
Это хотя бы отдаленно близко к тому, как Combine
предполагалось использовать?