HTML Diff
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&lt;String, Never&gt;() 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&lt;String, Never&gt;() 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&lt;String, Never&gt;("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&lt;String, Never&gt;("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