0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>На конференции WWDC 2019 был представлен новый фреймворк<strong>Combine</strong>. Всё последнее десятилетие среди программистов становились популярными декларативный и Event-based подходы к разработке приложений, т. к. они дают преимущество в скорости разработки приложений.</p>
1
<p>На конференции WWDC 2019 был представлен новый фреймворк<strong>Combine</strong>. Всё последнее десятилетие среди программистов становились популярными декларативный и Event-based подходы к разработке приложений, т. к. они дают преимущество в скорости разработки приложений.</p>
2
<p>Combine предоставляет следующие возможности: 1. Асинхронное выполнение кода. 2. Составные компоненты. 3. Более простой мультитрединг. 4. Кроссплатформенный код.</p>
2
<p>Combine предоставляет следующие возможности: 1. Асинхронное выполнение кода. 2. Составные компоненты. 3. Более простой мультитрединг. 4. Кроссплатформенный код.</p>
3
<p>Combine позволяет выполнять код "реактивно".</p>
3
<p>Combine позволяет выполнять код "реактивно".</p>
4
<h2>Publishers and Subscribers</h2>
4
<h2>Publishers and Subscribers</h2>
5
<p>Основой Combine является 2 концепции: 1.<strong>Subscriber</strong>выполняет роль Observer. 2.<strong>Publisher</strong>выполняет роль Observable.</p>
5
<p>Основой Combine является 2 концепции: 1.<strong>Subscriber</strong>выполняет роль Observer. 2.<strong>Publisher</strong>выполняет роль Observable.</p>
6
<p>Самый короткий пример их использования:</p>
6
<p>Самый короткий пример их использования:</p>
7
import Combine let pub = Just("Hello") _ = pub.sink { print($0) }<p>Объявляем константу, где в структуру<strong>Just</strong>оборачивается строка "Hello", - это наш паблишер, который оповестит только раз. Ниже добавляем подписку с замыканием с помощью метода<strong>sink</strong>. И этот пример напечатает в итоге строку Hello.</p>
7
import Combine let pub = Just("Hello") _ = pub.sink { print($0) }<p>Объявляем константу, где в структуру<strong>Just</strong>оборачивается строка "Hello", - это наш паблишер, который оповестит только раз. Ниже добавляем подписку с замыканием с помощью метода<strong>sink</strong>. И этот пример напечатает в итоге строку Hello.</p>
8
<h2>@Published Property Wrapper</h2>
8
<h2>@Published Property Wrapper</h2>
9
<p>В Swift 5.1 появилась возможность использовать Property Wrappers, которые изначально назывались Property Delegates. Это очередная обёртка в виде структуры, позволяющая добавлять на чтение или запись свойства (property) дополнительное поведение. Combine же даёт возможность использовать их через<strong>@Published</strong>.</p>
9
<p>В Swift 5.1 появилась возможность использовать Property Wrappers, которые изначально назывались Property Delegates. Это очередная обёртка в виде структуры, позволяющая добавлять на чтение или запись свойства (property) дополнительное поведение. Combine же даёт возможность использовать их через<strong>@Published</strong>.</p>
10
import Foundation import Combine class ObjectWithPublisher { @Published var someString: String = "" } var obj = ObjectWithPublisher() obj.$someString.sink(receiveValue: { print ("\($0)") }) obj.someString = "Hello Combine!"<p>Обращаться к таким врапперам можно, используя<strong>$</strong>перед свойством. Как и в прошлом примере, мы добавляем<strong>Subcriber</strong>с помощью метода<strong>sink</strong>, но свойство мы обновляем позже подписки. В итоге этот пример распечатает нам “Hello Combine!”</p>
10
import Foundation import Combine class ObjectWithPublisher { @Published var someString: String = "" } var obj = ObjectWithPublisher() obj.$someString.sink(receiveValue: { print ("\($0)") }) obj.someString = "Hello Combine!"<p>Обращаться к таким врапперам можно, используя<strong>$</strong>перед свойством. Как и в прошлом примере, мы добавляем<strong>Subcriber</strong>с помощью метода<strong>sink</strong>, но свойство мы обновляем позже подписки. В итоге этот пример распечатает нам “Hello Combine!”</p>
11
<h2>Subjects</h2>
11
<h2>Subjects</h2>
12
<p>В Combine такие сущности, как Subject также являются паблишерами, которым мы можем посылать события. Сейчас у нас есть 2 вида Subjects: 1.<strong>PassthroughSubject</strong>, с помощью которого вы получите все события, которые случились после вашей подписки. 2.<strong>CurrentValueSubject</strong>- получите всё тоже, что и с помощью<strong>PassthroughSubject</strong>, но также и предыдущее или инициализированное значение</p>
12
<p>В Combine такие сущности, как Subject также являются паблишерами, которым мы можем посылать события. Сейчас у нас есть 2 вида Subjects: 1.<strong>PassthroughSubject</strong>, с помощью которого вы получите все события, которые случились после вашей подписки. 2.<strong>CurrentValueSubject</strong>- получите всё тоже, что и с помощью<strong>PassthroughSubject</strong>, но также и предыдущее или инициализированное значение</p>
13
import Combine let subj = PassthroughSubject<String, Never>() let pub = subj.eraseToAnyPublisher() subj.send("Hello") let subscriber = pub.sink(receiveValue: { print($0) }) subj.send("Combine") subj.send("!")<p>Объявление Subjects требует от нас, чтобы кроме выходного типа мы также указали тип для ошибки, можем просто указать здесь<strong>Never</strong>. Функция eraseToAnyPublisher() делает нам Type Erasure для паблишера к типу<strong>AnyPublisher</strong>. Дальше уже знакомая нам подписка с помощью<strong>sink</strong>. События мы будет посылать с помощью метода<strong>send</strong>и получим лишь 2 последних отправления:</p>
13
import Combine let subj = PassthroughSubject<String, Never>() let pub = subj.eraseToAnyPublisher() subj.send("Hello") let subscriber = pub.sink(receiveValue: { print($0) }) subj.send("Combine") subj.send("!")<p>Объявление Subjects требует от нас, чтобы кроме выходного типа мы также указали тип для ошибки, можем просто указать здесь<strong>Never</strong>. Функция eraseToAnyPublisher() делает нам Type Erasure для паблишера к типу<strong>AnyPublisher</strong>. Дальше уже знакомая нам подписка с помощью<strong>sink</strong>. События мы будет посылать с помощью метода<strong>send</strong>и получим лишь 2 последних отправления:</p>
14
import Combine let subj = CurrentValueSubject<String, Never>("Bonjour") let pub = subj.eraseToAnyPublisher() subj.send("Hello") let subscriber = pub.sink(receiveValue: { print($0) }) subj.send("Combine") subj.send("!")<p>Использование<strong>CurrentValueSubject</strong>отличается тем, что нам нужно указать начальное значение. И результат мы получим :</p>
14
import Combine let subj = CurrentValueSubject<String, Never>("Bonjour") let pub = subj.eraseToAnyPublisher() subj.send("Hello") let subscriber = pub.sink(receiveValue: { print($0) }) subj.send("Combine") subj.send("!")<p>Использование<strong>CurrentValueSubject</strong>отличается тем, что нам нужно указать начальное значение. И результат мы получим :</p>
15
<p>Если же мы не закомментируем первое отправление до подписки, то вместо Hello нам придёт начальная строка Bonjour.</p>
15
<p>Если же мы не закомментируем первое отправление до подписки, то вместо Hello нам придёт начальная строка Bonjour.</p>
16
16