Swift Combine Première étape

Aperçu

Pour ceux qui découvrent Swift et veulent se faire une idée de Combine. Voici un code simple.

L'exemple d'aujourd'hui

Le but est de comprendre cela aujourd'hui! Tu n'as pas besoin de savoir. J'expliquerai plus tard. Ceux qui comprennent n'ont pas à le lire.

import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a).map{b,a in a + b}

publisher.sink{ added in
    print(added)
}
a.send(10)

Je ne pense pas que cela ait vraiment de sens, mais qu'est-ce qui est susceptible d'être affiché dans la sortie standard (impression)?

La réponse est

4
11

Deux lignes s'affichent. Le premier «4» est «3 + 1» Le 11 suivant est "10 + 1".

Importer pour le moment

Combiner l'importation


import Combine

Vous pouvez le faire avec. Disponible sur ** iOS 13 ** et supérieur.

Vous pouvez facilement l'essayer sur Playground.

Combiner terme

Éditeur et abonné sont les termes dont il faut se souvenir pour le moment dans Combine.

Nom Lecture japonaise que faites-vous
Publisher Éditeur Publier des données
Subscriber Abonné Abonnez-vous aux données

Vous n'avez pas à le comprendre, alors mémorisez 2 mots pour le moment! Publisher, Subscriber

Juste pour le moment

Just est (probablement) l'éditeur le plus simple.

Allons voir la définition pour le moment. (Extrait)

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public struct Just<Output> : Publisher {
   // ... (réduction)
}

Pour le moment, c'est un Publisher qui hérite du Publisher. Il semble être vrai qu'il ne peut être utilisé qu'avec iOS 13.0 ou supérieur.

Ce qui est écrit dans cette juste explication est

A publisher that emits an output to each subscriber just once, and then finishes.

De cette phrase, vous pouvez voir que:

N'oubliez pas que c'est un éditeur qui génère une valeur.

À propos de l'évier

Avec l'exemple de code


publisher.sink{ added in
    print(added)
}

Il y avait.

En regardant l'explication de ce [puits](https://developer.apple.com/documentation/combine/publisher/sink(receivevalue :)),

Attaches a subscriber with closure-based behavior to a publisher that never fails.

La signification est inconnue, mais il semble que cela attachera un abonné, alors utilisons-le.

Exemple 1

Que se passe-t-il si vous appelez think avec Just plus tôt?

Just(1).sink { r in
    print(r)
}

Cela affichera «1».

Il semble que l'éditeur (Just) ne sort 1 qu'une seule fois, et en le plongeant, il est entré dans r, donc «1» est affiché.

Exemple 2

Essayons également CurrentValueSubject <Int, Never> (3), dont nous n'avons pas encore discuté.

CurrentValueSubject<Int, Never>(3).sink { r in
    print(r)
}

Cela affichera «3»!

Quelle est la différence avec Just ...

À propos de CurrentValueSubject

Qu'est-ce que CurrentValueSubject? Regardons la définition.


@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
final public class CurrentValueSubject<Output, Failure> : Subject

Ce type semble être ** Sujet **. Ce n'était pas un éditeur! En outre, c'est la même chose que «Just»: il ne peut être utilisé que sur iOS 13.0 ou supérieur.

Description

A subject that wraps a single value and publishes a new element whenever the value changes.

N'est-ce pas seulement l'éditeur qui peut publier? J'irai aussi voir la définition de Sujet.

public protocol Subject : AnyObject, Publisher

Apparemment, l'objet semble être un ** type d'éditeur **.

Comparé à Just

Just Une sortiepourtant(just)Sortie une foisPublisher
CurrentValueSubject Enveloppez une valeur pour obtenir une nouvelle valeur lorsque la valeur changePublishFaireSubject

La différence avec Just est que lorsque la valeur change, il publie la nouvelle valeur! Essayons.


import Combine

let a = CurrentValueSubject<Int, Never>(3)

a.sink{ added in
    print(added)
}

a.value = 100
a.value = 10000
a.send(9999)

Qu'est-ce qui est susceptible d'être produit? La réponse est

3
100
10000
9999

Il imprime chaque fois qu'une .value est modifiée. De plus, a.send () semble être capable d'exprimer le changement de valeur.

Dernière ligne!

La plupart du premier exemple a été expliqué.

import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a).map{b,a in a + b}

publisher.sink{ added in
    print(added)
}
a.send(10)

Après cela, si vous savez let publisher = b.combineLatest (a) .map {b, a dans a + b}, il semble que vous puissiez comprendre la signification du code d'une manière ou d'une autre.

combineLatest

Tout d'abord, prêtons attention à b.combineLatest (a).

Qu'est-ce que ça veut dire?


let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

Donc, a et b sont des éditeurs.

Jetons un coup d'œil à la description de combineLatest.

Subscribes to an additional publisher and publishes a tuple upon receiving output from either publisher.

Ce type semble être à la fois Abonnez-vous et Publiez.

En fait utiliser

Essayez de le déplacer.

import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a).sink{r in
    print(r)
}

Que va-t-il se passer avec ça?

La bonne réponse est

(1, 3)

En parlant de cela, combineLatest a dit plus tôt qu'il retournerait un tuple.

Changeons la valeur de a. Ajoutez 3 lignes de code.

import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a).sink{r in
    print(r)
}

a.value = 4
a.value = 5
a.send(6)

Que se passe-t-il?

La bonne réponse est

(1, 3)
(1, 4)
(1, 5)
(1, 6)

La valeur de b reste inchangée et est imprimée en modifiant la valeur de a.

Avez-vous vu le mouvement?

Qui est combineLatest qui s'abonne et publie?

En regardant la définition,


    public func combineLatest<P>(_ other: P) -> Publishers.CombineLatest<Self, P> where P : Publisher, Self.Failure == P.Failure

C'est long et peu clair, mais il renvoie Publishers.CombineLatest <Self, P>.

Publishers.CombineLatest


public struct CombineLatest<A, B> : Publisher

C'est ** Publisher **.

Ainsi, «b.combineLatest (a)» est une fonction qui fait de deux éditeurs un éditeur.

map

la carte est

Transforms all elements from the upstream publisher with a provided closure.

Il semble que tout sera transformé.

En regardant la définition

public func map<T>(_ transform: @escaping (Self.Output) -> T) -> Publishers.Map<Self, T>

Après tout, cela renvoie toujours Publisher!

Exemple 1

L'exemple donné précédemment dans combineLatest.

import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a).sink{r in
    print(r)
}

a.value = 4
a.value = 5
a.send(6)

Le résultat est,

(1, 3)
(1, 4)
(1, 5)
(1, 6)

C'était.

Essayez d'ajouter une carte après combineLatest dans ce code.


import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a)
    .map{(b,a) in a+b}
    .sink{r in print(r)}

a.value = 4
a.value = 5
a.send(6)

Qu'est-ce qui est susceptible de revenir?

La bonne réponse est

4
5
6
7

c'est

(1, 3)
(1, 4)
(1, 5)
(1, 6)

Vous pouvez voir que chacun de ces résultats ajoute deux valeurs.

Exemple 2

J'ai changé .map {(b, a) dans a + b} en .map {(b, a) dans a}. Quelle sera la sortie?


import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a)
    .map{(b,a) in a}
    .sink{r in print(r)}

a.value = 4
a.value = 5
a.send(6)

La bonne réponse est

3
4
5
6

Sommaire

Pour utiliser Combine iOS 13.Au-dessus de 0import Combine
Ce qui est juste Sortir la valeur une seule foisPublisher
Qu'est-ce que l'évier Abonnez-vous à la sortie de valeur par Publisher(Subscribe)Peut être traité
CurrentValueSubject La valeur peut être modifiée et la valeur modifiée est sortie.Publisher(Subject)
Comment changer la valeur de CurrentValueSubject? CurrentValueSubject.Attribuer à value ou CurrentValueSubject.send(value)Entrez une valeur dans
Qu'est-ce que combineLatest Fait de deux éditeurs un éditeur et renvoie la valeur sous forme de taple.
Qu'est-ce que la carte Transformez toutes les valeurs de l'éditeur

Avez-vous compris le comportement du code en dessous de l'objectif?

import Combine

let a = CurrentValueSubject<Int, Never>(3)
let b = Just(1)

let publisher = b.combineLatest(a).map{b,a in a + b}

publisher.sink{ added in
    print(added)
}
a.send(10)

Recommended Posts

Swift Combine Première étape
JAVA (Première étape: édition Git Bush)