<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.2">Jekyll</generator><link href="https://lyfeoncloudnine.netlify.app/feed.xml" rel="self" type="application/atom+xml" /><link href="https://lyfeoncloudnine.netlify.app/" rel="alternate" type="text/html" /><updated>2025-08-09T07:42:49+00:00</updated><id>https://lyfeoncloudnine.netlify.app/feed.xml</id><entry><title type="html">Async/Await 알아보기</title><link href="https://lyfeoncloudnine.netlify.app/blog/asyncawait" rel="alternate" type="text/html" title="Async/Await 알아보기" /><published>2022-08-26T00:00:00+00:00</published><updated>2022-08-26T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/asyncawait</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/asyncawait"><![CDATA[<h3 id="asyncawait-이란">Async/Await 이란?</h3>

<p>Swift 5.5에 새롭게 추가된 기능으로 상당히 늦은감이 있지만 다뤄보려 한다.
기존의 비동기 코드를 동기처럼 동작하는 코드처럼 작성할 수 있다.
설명보다는 코드로 알아보자. 
먼저 기존의 비동기 코드부터 보자면</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 선언할 때</span>
<span class="kd">func</span> <span class="nf">getSomeData</span><span class="p">(</span><span class="nv">completion</span><span class="p">:</span> <span class="p">[</span><span class="kt">SomeData</span><span class="p">])</span> <span class="p">{</span>
    <span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">dataTask</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span> <span class="p">{</span> <span class="n">data</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">error</span> <span class="k">in</span>
        <span class="c1">// to do</span>
    <span class="p">}</span>
    <span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
<span class="p">}</span>

<span class="c1">// 사용할 때</span>
<span class="n">getSomeData</span> <span class="p">{</span> <span class="n">someData</span> <span class="k">in</span>
    <span class="c1">// to do</span>
<span class="p">}</span>
</code></pre></div></div>

<p>보통 이렇게 비동기 코드를 작성하게 되는데 문제는 이런 비동기 코드가 많으면 많아질수록 depth가 깊어지면서 가독성을 해치게 되며 이로 인해 여러 문제가 발생하게 된다. 
그래서 등장한게 바로 Async/Await 이다.
앞서 예시를 들었던 <code class="language-plaintext highlighter-rouge">URLSession</code>처럼 SDK에 포함된 기능은 기본적으로 제공하는 Async/Await 메서드들이 있다.
바로 알아보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 선언할 때</span>
<span class="kd">func</span> <span class="nf">getSomeData</span><span class="p">()</span> <span class="k">async</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="kt">SomeData</span><span class="p">]</span> <span class="p">{</span>
    <span class="k">let</span> <span class="p">(</span><span class="nv">data</span><span class="p">,</span> <span class="nv">response</span><span class="p">)</span> <span class="o">=</span> <span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">from</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>
    <span class="c1">// to do</span>
<span class="p">}</span>

<span class="c1">// 사용할 때</span>
<span class="k">let</span> <span class="nv">someData</span> <span class="o">=</span> <span class="k">try</span> <span class="k">await</span> <span class="nf">getSomeData</span><span class="p">()</span>
</code></pre></div></div>

<p>일단 여기엔 몇가지 규칙이 있다.
<code class="language-plaintext highlighter-rouge">async</code> 키워드는 <code class="language-plaintext highlighter-rouge">throws</code> 앞에 와야하며, <code class="language-plaintext highlighter-rouge">await</code> 키워드는 <code class="language-plaintext highlighter-rouge">try</code> 뒤에 와야 한다.
물론 <code class="language-plaintext highlighter-rouge">throws</code>와 <code class="language-plaintext highlighter-rouge">try</code> 키워드를 항상 붙여야 하는건 아니고 필요없다면 생략하면 된다.
또 <code class="language-plaintext highlighter-rouge">await</code> 키워드가 들어간 곳에서 시스템은 함수가 해당 함수가 종료될때까지 중지 될 수 있으며, 이렇게 중지되면 스레드는 자유롭게 다른 작업을 할 수 있게 된다.
그런 다음 <code class="language-plaintext highlighter-rouge">await</code>의 함수가 종료되면 그 다음줄을 마저 실행하게 된다.</p>

<h3 id="이미-작성된-코드를-활용하고-싶을-땐">이미 작성된 코드를 활용하고 싶을 땐?</h3>

<p><code class="language-plaintext highlighter-rouge">URLSession</code>처럼 애플에서 Async/Await으로 된 메서드들을 제공하면 좋은데, 그렇지 않은 기능이나 기존의 작성된 수많은 비동기 코드들은 어떻게 Async/Await을 활용할 수 있을까?
답은 <code class="language-plaintext highlighter-rouge">withCheckedThrowingContinuation</code>을 사용하는 것이다.
바로 코드로 알아보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">newGetSomeData</span><span class="p">()</span> <span class="k">async</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="kt">SomeData</span><span class="p">]</span> <span class="p">{</span>
    <span class="k">try</span> <span class="k">await</span> <span class="nf">withCheckedThrowingContinuation</span><span class="p">({</span> <span class="n">continuation</span> <span class="k">in</span>
        <span class="c1">// 에러</span>
        <span class="n">continuation</span><span class="o">.</span><span class="nf">resume</span><span class="p">(</span><span class="nv">throwing</span><span class="p">:</span> <span class="kt">SomeError</span><span class="p">)</span>
        <span class="c1">// 성공</span>
        <span class="n">continuation</span><span class="o">.</span><span class="nf">resume</span><span class="p">(</span><span class="nv">returning</span><span class="p">:</span> <span class="p">[</span><span class="kt">SomeData</span><span class="p">])</span>
    <span class="p">})</span>
<span class="p">}</span>
</code></pre></div></div>

<p>위처럼 <code class="language-plaintext highlighter-rouge">withCheckedThrowingContinuation</code> 를 사용하면 <code class="language-plaintext highlighter-rouge">CheckedContinuation</code>를 completion으로 받게 된다. 그리고 이 <code class="language-plaintext highlighter-rouge">CheckedContinuation</code>는 에러를 던질수도, 값을 리턴할 수도 있다.
다만 이 경우 꼭 성공이나 실패 어느 경우라도 무조건 <code class="language-plaintext highlighter-rouge">resume</code>를 호출해야한다. 그렇지 않으면 시스템은 영영 기다리게 되기 때문이다.</p>

<h3 id="추가-팁">추가 팁</h3>

<p>만약 여러 비동기 코드를 순차적으로 실행해야 하는 경우와 반대로 동시에 실행해야 하는 경우 어떻게 활용할 수 있을까?
먼저 순차적으로 실행해야 하는 경우를 보자</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">id</span> <span class="o">=</span> <span class="k">try</span> <span class="k">await</span> <span class="nf">getID</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">books</span> <span class="o">=</span> <span class="k">try</span> <span class="k">await</span> <span class="nf">getBooks</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="n">id</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">favoriteBooks</span> <span class="o">=</span> <span class="k">try</span> <span class="k">await</span> <span class="nf">getFavoriteBooks</span><span class="p">(</span><span class="nv">books</span><span class="p">:</span> <span class="n">books</span><span class="p">)</span>
</code></pre></div></div>

<p>순차적인 경우는 쉽다. 그냥 순서대로 작성하면 된다.
알아서 await에서 코드가 중지되고 스레드는 다른 일을 하게 될 것이다.
그러나 만약 모든 코드를 동시에 실행하고 싶다면 어떻게 해야할까?</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="k">let</span> <span class="nv">firstPhoto</span> <span class="o">=</span> <span class="nf">downloadPhoto</span><span class="p">(</span><span class="nv">named</span><span class="p">:</span> <span class="n">photoNames</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">async</span> <span class="k">let</span> <span class="nv">secondPhoto</span> <span class="o">=</span> <span class="nf">downloadPhoto</span><span class="p">(</span><span class="nv">named</span><span class="p">:</span> <span class="n">photoNames</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">async</span> <span class="k">let</span> <span class="nv">thirdPhoto</span> <span class="o">=</span> <span class="nf">downloadPhoto</span><span class="p">(</span><span class="nv">named</span><span class="p">:</span> <span class="n">photoNames</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>

<span class="k">let</span> <span class="nv">photos</span> <span class="o">=</span> <span class="k">await</span> <span class="p">[</span><span class="n">firstPhoto</span><span class="p">,</span> <span class="n">secondPhoto</span><span class="p">,</span> <span class="n">thirdPhoto</span><span class="p">]</span>
</code></pre></div></div>

<p>이처럼 작성하게 되면 <code class="language-plaintext highlighter-rouge">await</code> 키워드에서 코드가 일시정지되고, 배열안의 모든 함수가 종료되고 값이 할당되면 다시 재개된다.</p>]]></content><author><name></name></author><category term="Swift" /><summary type="html"><![CDATA[Swift의 새로운 기능 Async/Await에 대해 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/Swift.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/Swift.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">PinLayout 처럼 Auto Layout 코드 작성하기</title><link href="https://lyfeoncloudnine.netlify.app/blog/layoutsugar" rel="alternate" type="text/html" title="PinLayout 처럼 Auto Layout 코드 작성하기" /><published>2022-05-24T00:00:00+00:00</published><updated>2022-05-24T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/layoutsugar</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/layoutsugar"><![CDATA[<h3 id="pinlayout이란">PinLayout이란?</h3>

<p><a href="https://github.com/layoutBox/PinLayout">PinLayout</a></p>

<h3 id="왜-pinlayout을-쓰지-않는지">왜 PinLayout을 쓰지 않는지?</h3>

<p>PinLayout이 Auto Layout보다 성능이 좋다고는 하나, 좋은 성능의 폰이 보급됨에 따라 그 성능이 차이가 크지 않다고 느끼며, 그에 따라 굳이 PinLayout에서 제공하는 수많은 기능을 공부하기엔 시간 낭비같았다.
실제로 PinLayout에서 제공하는 퍼포먼스 표를 보면 5s부터 X까지만 비교가 되어있다.
아마 최신 기종일수록 그 격차가 좁혀져서 유의미한 차이는 없을거라고 본다.
하지만 one view, one line 은 인상깊었다.
나는 뷰를 만들때 스토리보드를 쓰지 않고, 코드로 작성한다.
간단하게 <code class="language-plaintext highlighter-rouge">UIImageView</code>와 <code class="language-plaintext highlighter-rouge">UILabel</code> 두개만 있는 뷰를 구성한다고 가정해보자.
그러면 보통 다음과 같이 작성할 것이다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">UIKit</span>

<span class="kd">import</span> <span class="kt">Then</span>

<span class="kd">final</span> <span class="kd">class</span> <span class="kt">TestView</span><span class="p">:</span> <span class="kt">UIView</span> <span class="p">{</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">imageView</span> <span class="o">=</span> <span class="kt">UIImageView</span><span class="p">()</span><span class="o">.</span><span class="n">then</span> <span class="p">{</span>
        <span class="nv">$0</span><span class="o">.</span><span class="n">layer</span><span class="o">.</span><span class="n">cornerRadius</span> <span class="o">=</span> <span class="mi">12</span>
        <span class="nv">$0</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">lightGray</span>
        <span class="nv">$0</span><span class="o">.</span><span class="n">clipsToBounds</span> <span class="o">=</span> <span class="kc">true</span>
    <span class="p">}</span>
    
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">label</span> <span class="o">=</span> <span class="kt">UILabel</span><span class="p">()</span><span class="o">.</span><span class="n">then</span> <span class="p">{</span>
        <span class="nv">$0</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"레이블입니다."</span>
        <span class="nv">$0</span><span class="o">.</span><span class="n">font</span> <span class="o">=</span> <span class="o">.</span><span class="nf">systemFont</span><span class="p">(</span><span class="nv">ofSize</span><span class="p">:</span> <span class="mi">20</span><span class="p">)</span>
    <span class="p">}</span>
    
    <span class="k">override</span> <span class="nf">init</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="kt">CGRect</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="n">frame</span><span class="p">)</span>
        
        <span class="nf">configureLayout</span><span class="p">()</span>
    <span class="p">}</span>
    
    <span class="kd">required</span> <span class="nf">init</span><span class="p">?(</span><span class="nv">coder</span><span class="p">:</span> <span class="kt">NSCoder</span><span class="p">)</span> <span class="p">{</span>
        <span class="nf">fatalError</span><span class="p">(</span><span class="s">"not support"</span><span class="p">)</span>
    <span class="p">}</span>
    
    <span class="kd">private</span> <span class="kd">func</span> <span class="nf">configureLayout</span><span class="p">()</span> <span class="p">{</span>
        <span class="nf">addSubview</span><span class="p">(</span><span class="n">imageView</span><span class="p">)</span>
        <span class="nf">addSubview</span><span class="p">(</span><span class="n">label</span><span class="p">)</span>
        
        <span class="n">imageView</span><span class="o">.</span><span class="n">translatesAutoresizingMaskIntoConstraints</span> <span class="o">=</span> <span class="kc">false</span>
        <span class="n">label</span><span class="o">.</span><span class="n">translatesAutoresizingMaskIntoConstraints</span> <span class="o">=</span> <span class="kc">false</span>
        
        <span class="kt">NSLayoutConstraint</span><span class="o">.</span><span class="nf">activate</span><span class="p">([</span>
            <span class="n">imageView</span><span class="o">.</span><span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">topAnchor</span><span class="p">),</span>
            <span class="n">imageView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">leadingAnchor</span><span class="p">),</span>
            <span class="n">imageView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">bottomAnchor</span><span class="p">),</span>
            <span class="n">imageView</span><span class="o">.</span><span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalToConstant</span><span class="p">:</span> <span class="mi">200</span><span class="p">),</span>
            <span class="n">imageView</span><span class="o">.</span><span class="n">heightAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalToConstant</span><span class="p">:</span> <span class="mi">200</span><span class="p">),</span>
            
            <span class="n">label</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">imageView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">10</span><span class="p">),</span>
            <span class="n">label</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="o">-</span><span class="mi">10</span><span class="p">),</span>
            <span class="n">label</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">imageView</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="p">)</span>
        <span class="p">])</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><img src="/images/blog/22-05-24/01.png" /></p>

<p>그러면 다음과 같은 <code class="language-plaintext highlighter-rouge">View</code>가 만들어진다.
되게 간단한 구성임에도 여러 줄을 작성해야 해서 디자인 작업을 하다보면 타이핑에 지칠 때도 있다.
또 다음에 보면 줄이 너무 길어서 가독성이 떨어질 때도 많았다.
그래서 PinLayout의 one view, one line을 도입해보기로 했다.</p>

<h3 id="uiview-extension">UIView Extension</h3>

<p>최초의 아이디어는 <code class="language-plaintext highlighter-rouge">UIView</code>를 리턴해주는 메소드를 만들고, 그 안에서 코드를 작성해두면 체이닝으로 쓸 수 있겠다고 생각했다.
그리고 <code class="language-plaintext highlighter-rouge">UIView</code>를 만들게 되면 <code class="language-plaintext highlighter-rouge">translatesAutoresizingMaskIntoConstraints</code>를 <code class="language-plaintext highlighter-rouge">false</code>로 줘야해서 관련 extension도 추가했다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">UIView</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">addSubviews</span><span class="p">(</span><span class="n">_</span> <span class="nv">views</span><span class="p">:</span> <span class="kt">UIView</span><span class="o">...</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">views</span><span class="o">.</span><span class="n">forEach</span> <span class="p">{</span>
            <span class="nv">$0</span><span class="o">.</span><span class="n">translatesAutoresizingMaskIntoConstraints</span> <span class="o">=</span> <span class="kc">false</span>
            <span class="nf">addSubview</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">top</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutYAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">leading</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutXAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">bottom</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutYAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">trailing</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutXAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">width</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalToConstant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">width</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutDimension</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">height</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">heightAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalToConstant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">height</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutDimension</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">heightAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">centerX</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutXAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">centerXAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>

    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">centerY</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutYAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UIView</span> <span class="p">{</span>
        <span class="n">centerYAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>덕분에 이렇게 코드를 작성할 수 있게 됐다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">configureLayout</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">backgroundColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">white</span>
    
    <span class="nf">addSubviews</span><span class="p">(</span><span class="n">imageView</span><span class="p">,</span> <span class="n">label</span><span class="p">)</span>
    
    <span class="n">imageView</span><span class="o">.</span><span class="nf">top</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">topAnchor</span><span class="p">)</span><span class="o">.</span><span class="nf">leading</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">leadingAnchor</span><span class="p">)</span><span class="o">.</span><span class="nf">bottom</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">bottomAnchor</span><span class="p">)</span><span class="o">.</span><span class="nf">width</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span><span class="o">.</span><span class="nf">height</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span>
    <span class="n">label</span><span class="o">.</span><span class="nf">leading</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">imageView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="nf">trailing</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="o">-</span><span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="nf">centerY</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">imageView</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>처음 코드와 비교해보면 비약적으로 단축되었고, one view, one line이 되었다.
그런데 사용하면서 조금 불편한 점이 있었다.
바로 topAnchor, leadingAnchor 등 UIView의 Property와 네이밍이 중복되어 같은 레이어에서 보여지는 것이 불편했고, 가끔 실수나 잘못사용하게 될 수 있다고 생각했다.</p>

<p><img src="/images/blog/22-05-24/02.png" /></p>

<p>그래서 PinLayout 처럼 계층을 분리하고, 내가 새로 추가한 코드만 쓸 수 있게 따로 클래스를 정의하기로 했다.
우선 나는 Hook 라는 네이밍을 사용하기로 했고 <code class="language-plaintext highlighter-rouge">Property</code>를 추가했다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">UIView</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">hook</span><span class="p">:</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="kt">Hook</span><span class="p">(</span><span class="nv">view</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>그리고 <code class="language-plaintext highlighter-rouge">Hook</code> 클래스를 정의했다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">Hook</span> <span class="p">{</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">view</span><span class="p">:</span> <span class="kt">UIView</span>
    
    <span class="nf">init</span><span class="p">(</span><span class="nv">view</span><span class="p">:</span> <span class="kt">UIView</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">view</span> <span class="o">=</span> <span class="n">view</span>
    <span class="p">}</span>
    
    <span class="c1">// MARK: - Top, Leading, Bottom, Trailing</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">top</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutYAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">topAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">leading</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutXAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">bottom</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutYAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">trailing</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutXAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="c1">// MARK: - Combination</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">all</span><span class="p">(</span><span class="n">to</span> <span class="nv">superView</span><span class="p">:</span> <span class="kt">UIView</span><span class="p">,</span> <span class="nv">topConstant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">leadingConstant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">bottomConstant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">trailingConstant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">hook</span>
            <span class="o">.</span><span class="nf">top</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">superView</span><span class="o">.</span><span class="n">topAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">topConstant</span><span class="p">)</span>
            <span class="o">.</span><span class="nf">leading</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">superView</span><span class="o">.</span><span class="n">leadingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">leadingConstant</span><span class="p">)</span>
            <span class="o">.</span><span class="nf">bottom</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">superView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">bottomConstant</span><span class="p">)</span>
            <span class="o">.</span><span class="nf">trailing</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">superView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">trailingConstant</span><span class="p">)</span>
        
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="c1">// MARK: - Width &amp; Height</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">width</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalToConstant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">width</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutDimension</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">height</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">heightAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalToConstant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">height</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutDimension</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">heightAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="c1">// MARK: - Center</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">centerX</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutXAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">centerXAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
    
    <span class="kd">@discardableResult</span>
    <span class="kd">func</span> <span class="nf">centerY</span><span class="p">(</span><span class="n">to</span> <span class="nv">anchor</span><span class="p">:</span> <span class="kt">NSLayoutAnchor</span><span class="o">&lt;</span><span class="kt">NSLayoutYAxisAnchor</span><span class="o">&gt;</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="kt">CGFloat</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Hook</span> <span class="p">{</span>
        <span class="n">view</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="o">.</span><span class="nf">constraint</span><span class="p">(</span><span class="nv">equalTo</span><span class="p">:</span> <span class="n">anchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="n">constant</span><span class="p">)</span><span class="o">.</span><span class="n">isActive</span> <span class="o">=</span> <span class="kc">true</span>
        <span class="k">return</span> <span class="k">self</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이제는 <code class="language-plaintext highlighter-rouge">UIView</code>의 <code class="language-plaintext highlighter-rouge">hook</code> 프로퍼티에서만 내가 추가한 코드를 쓸 수 있어 기존 코드와 분리가 되었고, 더욱 명확하고 안전하게 쓸 수 있게 되었다.</p>

<p><img src="/images/blog/22-05-24/03.png" /></p>

<h3 id="결과">결과</h3>

<p>자 이제 코드가 이렇게 바뀌었다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">configureLayout</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">backgroundColor</span> <span class="o">=</span> <span class="o">.</span><span class="n">white</span>
    
    <span class="nf">addSubviews</span><span class="p">(</span><span class="n">imageView</span><span class="p">,</span> <span class="n">label</span><span class="p">)</span>
    
    <span class="n">imageView</span><span class="o">.</span><span class="n">hook</span><span class="o">.</span><span class="nf">top</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">topAnchor</span><span class="p">)</span><span class="o">.</span><span class="nf">leading</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">leadingAnchor</span><span class="p">)</span><span class="o">.</span><span class="nf">bottom</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">bottomAnchor</span><span class="p">)</span><span class="o">.</span><span class="nf">width</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span><span class="o">.</span><span class="nf">height</span><span class="p">(</span><span class="nv">constant</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span>
    <span class="n">label</span><span class="o">.</span><span class="n">hook</span><span class="o">.</span><span class="nf">leading</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">imageView</span><span class="o">.</span><span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="nf">trailing</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">trailingAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="o">-</span><span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="nf">centerY</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="n">imageView</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="cocoapods--spm">CocoaPods &amp; SPM</h3>

<p>이렇게 쓰다가 이 글을 남긴지 6개월이 지나고 점점 이것저것 추가해서 쓰면서 <code class="language-plaintext highlighter-rouge">NSLayoutConstraint</code>를 Wrapping해서 아예 라이브러리를 만들게 되었다.
CocoaPods와 SPM 둘다 지원합니다.</p>

<p><a href="https://github.com/lyfeoncloudnine/hook">Hook (Github 바로가기)</a></p>]]></content><author><name></name></author><category term="iOS" /><summary type="html"><![CDATA[PinLayout처럼 Auto Layout 코드를 작성하는 방법에 대해 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/View.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/View.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">SwiftUI의 Property Wrapper 훑어보기</title><link href="https://lyfeoncloudnine.netlify.app/blog/propertywrapper" rel="alternate" type="text/html" title="SwiftUI의 Property Wrapper 훑어보기" /><published>2021-09-28T00:00:00+00:00</published><updated>2021-09-28T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/propertywrapper</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/propertywrapper"><![CDATA[<h3 id="property-wrapper-종류">Property Wrapper 종류</h3>

<ul>
  <li>State</li>
  <li>Binding</li>
  <li>ObservableObject</li>
  <li>EnvironmentObject</li>
  <li>StateObject</li>
  <li>AppStorage</li>
</ul>

<h3 id="state">State</h3>

<p>우선 아주 간단한 <code class="language-plaintext highlighter-rouge">Text</code>만 있는 <code class="language-plaintext highlighter-rouge">View</code>를 그려보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">VStack</span> <span class="p">{</span>
            <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이제 이 <code class="language-plaintext highlighter-rouge">View</code>에 <code class="language-plaintext highlighter-rouge">Button</code>을 추가하고, <code class="language-plaintext highlighter-rouge">Button</code>을 누르면 <code class="language-plaintext highlighter-rouge">myName</code>의 값을 바꾸도록 해보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">VStack</span> <span class="p">{</span>
    <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
    
    <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이렇게 <code class="language-plaintext highlighter-rouge">Vstack</code> 안에 <code class="language-plaintext highlighter-rouge">Button</code>을 추가했고 <code class="language-plaintext highlighter-rouge">myName</code>을 바꾸려고 했다.
그런데 빌드가 될까? 역시 빌드가 안된다.
그 이유는 우선 <code class="language-plaintext highlighter-rouge">ContentView</code>는 구조체다. Swift에서 구조체는 구조체 안에서 자신의 값을 바꿀 수 없다.
구조체가 자신의 값을 바꾸기 위해서는 <code class="language-plaintext highlighter-rouge">mutating</code> 키워드가 필요한데, <code class="language-plaintext highlighter-rouge">mutating</code> 키워드는 <code class="language-plaintext highlighter-rouge">Computed Property</code>에서 사용이 불가능하다.
그리고 <code class="language-plaintext highlighter-rouge">body</code>를 보면 <code class="language-plaintext highlighter-rouge">body</code>는 <code class="language-plaintext highlighter-rouge">Computed Property</code> 임을 알 수 있다.
따라서 우리는 원래대로라면 <code class="language-plaintext highlighter-rouge">myName</code>의 값을 바꿀 수 없는 것이고, 이를 해결하기 위해서 SwiftUI에서는 여러 Property Wrapper가 등장했고 그 중 하나가 바로 <code class="language-plaintext highlighter-rouge">State</code>이다.</p>

<p><code class="language-plaintext highlighter-rouge">State</code>는 값 자체가 아니고 그 안에 들어있는 값을 일고 쓰는 수단일 뿐이다.
SwiftUI에서는 <code class="language-plaintext highlighter-rouge">State</code>가 변경되면 <code class="language-plaintext highlighter-rouge">body</code>를 다시 계산하면서 뷰가 갱신되게 된다.
즉 <code class="language-plaintext highlighter-rouge">State</code> 어노테이션은 SwiftUI에서 값을 읽고 쓸 수 있게 해주며 뷰를 갱신할 수 있게 한다.</p>

<p>이제 이렇게 바꿔보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@State</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">VStack</span> <span class="p">{</span>
            <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
            
            <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이제 <code class="language-plaintext highlighter-rouge">Button</code>을 누르면 <code class="language-plaintext highlighter-rouge">Text</code>가 잘 바뀌는 것을 알 수 있다.</p>

<h3 id="binding">Binding</h3>

<p><code class="language-plaintext highlighter-rouge">@Binding</code> Property Wrapper는 <code class="language-plaintext highlighter-rouge">State</code>와 똑같지만 외부로부터 주입받는 경우에 사용한다.
그래서 사용하는 내부에서 초기화하지 않고 타입만 정의해서 사용한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@State</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">NavigationView</span><span class="p">(</span><span class="nv">content</span><span class="p">:</span> <span class="p">{</span>
            <span class="kt">VStack</span> <span class="p">{</span>
                <span class="kt">NavigationLink</span><span class="p">(</span><span class="nv">destination</span><span class="p">:</span> <span class="kt">ContentSubview</span><span class="p">(</span><span class="nv">myName</span><span class="p">:</span> <span class="n">myName</span><span class="p">))</span> <span class="p">{</span>
                    <span class="kt">Text</span><span class="p">(</span><span class="s">"Move To ContentSubview"</span><span class="p">)</span>
                <span class="p">}</span>
                
                <span class="kt">Spacer</span><span class="p">()</span>
                
                <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
                
                <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">ContentSubview</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@Binding</span> <span class="k">var</span> <span class="nv">myName</span><span class="p">:</span> <span class="kt">String</span> <span class="c1">// 타입만 정의</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">VStack</span> <span class="p">{</span>
            <span class="kt">Text</span><span class="p">(</span><span class="s">"Hello, </span><span class="se">\(</span><span class="n">myName</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
            
            <span class="kt">Button</span><span class="p">(</span><span class="s">"Reset Name"</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">myName</span> <span class="o">=</span> <span class="s">""</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이제 <code class="language-plaintext highlighter-rouge">ContentSubview</code>에서의 일어난 <code class="language-plaintext highlighter-rouge">myName</code>의 변화는 <code class="language-plaintext highlighter-rouge">ContentView</code>에도 반영된다.
같은 소스를 공유하기 때문이다.</p>

<h3 id="observableobject">ObservableObject</h3>

<p><code class="language-plaintext highlighter-rouge">@State</code>와 <code class="language-plaintext highlighter-rouge">@Binding</code>프로퍼티 래퍼는 Value Type에서만 동작한다.
그렇다면 클래스와 같은 Reference Type은 어떻게 해야할까?
클래스와 같은 Reference Type은 <code class="language-plaintext highlighter-rouge">ObservableObject</code>를 채택해야 한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyInfo</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    <span class="k">var</span> <span class="nv">myAge</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">var</span> <span class="nv">address</span> <span class="o">=</span> <span class="s">""</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">myInfo</span> <span class="o">=</span> <span class="kt">MyInfo</span><span class="p">()</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">NavigationView</span><span class="p">(</span><span class="nv">content</span><span class="p">:</span> <span class="p">{</span>
            <span class="kt">VStack</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
                
                <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이제 <code class="language-plaintext highlighter-rouge">myName</code> 대신 <code class="language-plaintext highlighter-rouge">MyInfo</code>라는 클래스를 정의하고 여기에 필요한 Property를 만들었다.
아까처럼 <code class="language-plaintext highlighter-rouge">Button</code>을 누르면 <code class="language-plaintext highlighter-rouge">myInfo</code>의 <code class="language-plaintext highlighter-rouge">myName</code>을 변경한다.
그러면 <code class="language-plaintext highlighter-rouge">Text</code>가 바뀔까? 당연히 안바뀐다.
아까 <code class="language-plaintext highlighter-rouge">@State</code> 처럼 특정 어노테이션이 있어야 <code class="language-plaintext highlighter-rouge">body</code>를 다시 계산하고 뷰를 갱신할 수 있는데, 여기에는 어디에도 뷰를 다시 그릴 포인트가 없다.
클래스는 <code class="language-plaintext highlighter-rouge">ObservableObject</code>를 채택하고 있는데, 이제 여기서 Property가 바뀔때마다 뷰를 갱신할 수 있도록 <code class="language-plaintext highlighter-rouge">Published</code> 어노테이션을 추가해보자.
이 어노테이션은 말 그대로 변화가 생길때마다 이 변화를 발행한다.
<code class="language-plaintext highlighter-rouge">Published</code>는 <code class="language-plaintext highlighter-rouge">View</code>를 갱신하기 때문에 UI와 관련된 Property에 한해서 써야 한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyInfo</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    <span class="k">var</span> <span class="nv">myAge</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">var</span> <span class="nv">address</span> <span class="o">=</span> <span class="s">""</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">myInfo</span> <span class="o">=</span> <span class="kt">MyInfo</span><span class="p">()</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">NavigationView</span><span class="p">(</span><span class="nv">content</span><span class="p">:</span> <span class="p">{</span>
            <span class="kt">VStack</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
                
                <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>또 모든 변화에 Publish하지 않고 특정 조건에 따라 Publish 할 수도 있다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyInfo</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span> <span class="p">{</span>
        <span class="k">willSet</span> <span class="p">{</span>
            <span class="k">if</span> <span class="n">newValue</span> <span class="o">==</span> <span class="s">"leo"</span> <span class="p">{</span> <span class="c1">// 이런식으로 특정 조건에만 변화를 Publish 할 수도 있다.</span>
                <span class="n">objectWillChange</span><span class="o">.</span><span class="nf">send</span><span class="p">()</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">var</span> <span class="nv">myAge</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">var</span> <span class="nv">address</span> <span class="o">=</span> <span class="s">""</span>
<span class="p">}</span>
</code></pre></div></div>

<p>이대로 끝일까? 역시나 No. <code class="language-plaintext highlighter-rouge">MyInfo</code>는 <code class="language-plaintext highlighter-rouge">ObservableObject</code>를 채택하고 있고, 여기서 <code class="language-plaintext highlighter-rouge">Published</code>된 값을 통해 뷰를 갱신하고 싶다면 사용하는 쪽에서 선언할 때 <code class="language-plaintext highlighter-rouge">@State</code> 나 <code class="language-plaintext highlighter-rouge">@Binding</code>과 같은 Property Wrapper를 사용해야 한다.</p>

<h3 id="stateobject--observedobject">StateObject &amp; ObservedObject</h3>

<p>아까 말했듯 <code class="language-plaintext highlighter-rouge">@State</code>와 <code class="language-plaintext highlighter-rouge">@Binding</code>은 Value Type과 함께 동작한다.
우리는 위에서 Reference Type인 클래스를 관찰 가능한 <code class="language-plaintext highlighter-rouge">ObservableObject</code>로 만들었으니 이와 함께 동작하기 위해 <code class="language-plaintext highlighter-rouge">@StateObject</code>와 <code class="language-plaintext highlighter-rouge">@ObservableObject</code>가 필요하다.
둘의 차이는 <code class="language-plaintext highlighter-rouge">@State</code>가 Reference Type에서 <code class="language-plaintext highlighter-rouge">@StateObject</code>가 되며 <code class="language-plaintext highlighter-rouge">@Binding</code>이 <code class="language-plaintext highlighter-rouge">@ObservedObject</code>가 된다.
그래서 <code class="language-plaintext highlighter-rouge">@Binding</code>과 마찬가지로 <code class="language-plaintext highlighter-rouge">ObservedObject</code>는 초기값을 제공할 필요가 없다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyInfo</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    <span class="k">var</span> <span class="nv">myAge</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">var</span> <span class="nv">address</span> <span class="o">=</span> <span class="s">""</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@StateObject</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">myInfo</span> <span class="o">=</span> <span class="kt">MyInfo</span><span class="p">()</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">NavigationView</span><span class="p">(</span><span class="nv">content</span><span class="p">:</span> <span class="p">{</span>
            <span class="kt">VStack</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
                
                <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">ContentSubView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@ObservedObject</span> <span class="k">var</span> <span class="nv">myInfo</span><span class="p">:</span> <span class="kt">MyInfo</span> <span class="c1">// 타입만 정의</span>

    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">Text</span><span class="p">(</span><span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="environmentobject">EnvironmentObject</h3>

<p><code class="language-plaintext highlighter-rouge">EnvironmentObject</code>는 싱글톤 객체로 이해하면 쉽다.
대신 <code class="language-plaintext highlighter-rouge">View</code>에서 생성할 수 없으며 <code class="language-plaintext highlighter-rouge">@ObservedObject</code> 처럼 외부에서 주입해야만 한다.
바로 코드를 보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyInfo</span><span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
    <span class="kd">@Published</span> <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    <span class="k">var</span> <span class="nv">myAge</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">var</span> <span class="nv">address</span> <span class="o">=</span> <span class="s">""</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@EnvironmentObject</span> <span class="k">var</span> <span class="nv">myInfo</span><span class="p">:</span> <span class="kt">MyInfo</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">NavigationView</span><span class="p">(</span><span class="nv">content</span><span class="p">:</span> <span class="p">{</span>
            <span class="kt">VStack</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is '</span><span class="se">\(</span><span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span><span class="se">)</span><span class="s">'"</span><span class="p">)</span>
                
                <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">myInfo</span><span class="o">.</span><span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>구조 자체는 아까와 똑같은데 <code class="language-plaintext highlighter-rouge">myInfo</code>가 <code class="language-plaintext highlighter-rouge">EnvironmentObject</code> 어노테이션으로 작성됐고 초기화되지 않았다.
이 <code class="language-plaintext highlighter-rouge">myInfo</code>는 앱의 전역에서 쓰이는 객체라고 가정하고 특정 화면에서 <code class="language-plaintext highlighter-rouge">MyInfo</code>에 접근하고 싶다면 위와 같이 작성하면 된다.
그런데 일반적인 싱글톤 객체의 경우 싱글톤 객체에 접근하는 순간 초기화가 일어나는데, 아까 말했듯 <code class="language-plaintext highlighter-rouge">EnvironmentObject</code>는 <code class="language-plaintext highlighter-rouge">View</code> 안에서 초기화될 수 없다.
그럼 도대체 언제 초기화되어서 메모리에 올라가느냐? 바로 Root View를 초기화할때다.</p>

<p><code class="language-plaintext highlighter-rouge">SceneDelegate</code>를 가보자</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// SceneDelegate.swift</span>
<span class="kd">func</span> <span class="nf">scene</span><span class="p">(</span><span class="n">_</span> <span class="nv">scene</span><span class="p">:</span> <span class="kt">UIScene</span><span class="p">,</span> <span class="n">willConnectTo</span> <span class="nv">session</span><span class="p">:</span> <span class="kt">UISceneSession</span><span class="p">,</span> <span class="n">options</span> <span class="nv">connectionOptions</span><span class="p">:</span> <span class="kt">UIScene</span><span class="o">.</span><span class="kt">ConnectionOptions</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.</span>
    <span class="c1">// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.</span>
    <span class="c1">// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).</span>

    <span class="c1">// Create the SwiftUI view that provides the window contents.</span>
    <span class="k">let</span> <span class="nv">contentView</span> <span class="o">=</span> <span class="kt">ContentView</span><span class="p">()</span>

    <span class="c1">// Use a UIHostingController as window root view controller.</span>
    <span class="k">if</span> <span class="k">let</span> <span class="nv">windowScene</span> <span class="o">=</span> <span class="n">scene</span> <span class="k">as?</span> <span class="kt">UIWindowScene</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">window</span> <span class="o">=</span> <span class="kt">UIWindow</span><span class="p">(</span><span class="nv">windowScene</span><span class="p">:</span> <span class="n">windowScene</span><span class="p">)</span>
        <span class="n">window</span><span class="o">.</span><span class="n">rootViewController</span> <span class="o">=</span> <span class="kt">UIHostingController</span><span class="p">(</span><span class="nv">rootView</span><span class="p">:</span> <span class="n">contentView</span><span class="p">)</span>
        <span class="k">self</span><span class="o">.</span><span class="n">window</span> <span class="o">=</span> <span class="n">window</span>
        <span class="n">window</span><span class="o">.</span><span class="nf">makeKeyAndVisible</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>여기서 <code class="language-plaintext highlighter-rouge">ContentView</code>를 초기화활때 <code class="language-plaintext highlighter-rouge">.environmentObject(_:)</code>를 호출해서 <code class="language-plaintext highlighter-rouge">EnvironmentObject</code> 들을 초기화해야 한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">scene</span><span class="p">(</span><span class="n">_</span> <span class="nv">scene</span><span class="p">:</span> <span class="kt">UIScene</span><span class="p">,</span> <span class="n">willConnectTo</span> <span class="nv">session</span><span class="p">:</span> <span class="kt">UISceneSession</span><span class="p">,</span> <span class="n">options</span> <span class="nv">connectionOptions</span><span class="p">:</span> <span class="kt">UIScene</span><span class="o">.</span><span class="kt">ConnectionOptions</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.</span>
    <span class="c1">// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.</span>
    <span class="c1">// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).</span>

    <span class="c1">// Create the SwiftUI view that provides the window contents.</span>
    <span class="k">let</span> <span class="nv">contentView</span> <span class="o">=</span> <span class="kt">ContentView</span><span class="p">()</span>
        <span class="o">.</span><span class="nf">environmentObject</span><span class="p">(</span><span class="kt">MyInfo</span><span class="p">())</span>

    <span class="c1">// Use a UIHostingController as window root view controller.</span>
    <span class="k">if</span> <span class="k">let</span> <span class="nv">windowScene</span> <span class="o">=</span> <span class="n">scene</span> <span class="k">as?</span> <span class="kt">UIWindowScene</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">window</span> <span class="o">=</span> <span class="kt">UIWindow</span><span class="p">(</span><span class="nv">windowScene</span><span class="p">:</span> <span class="n">windowScene</span><span class="p">)</span>
        <span class="n">window</span><span class="o">.</span><span class="n">rootViewController</span> <span class="o">=</span> <span class="kt">UIHostingController</span><span class="p">(</span><span class="nv">rootView</span><span class="p">:</span> <span class="n">contentView</span><span class="p">)</span>
        <span class="k">self</span><span class="o">.</span><span class="n">window</span> <span class="o">=</span> <span class="n">window</span>
        <span class="n">window</span><span class="o">.</span><span class="nf">makeKeyAndVisible</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>또 여러개의 <code class="language-plaintext highlighter-rouge">EnvironmentObject</code>가 필요하다면 체이닝을 통해 계속 추가할 수 있다.</p>

<h3 id="appstorage">AppStorage</h3>

<p><code class="language-plaintext highlighter-rouge">AppStorage</code>는 <code class="language-plaintext highlighter-rouge">UserDefaults</code>를 래핑한 것이므로 쉽다.
바로 코드로 넘어가자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">ContentView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
    <span class="kd">@AppStorage</span><span class="p">(</span><span class="s">"value"</span><span class="p">)</span> <span class="k">var</span> <span class="nv">myName</span> <span class="o">=</span> <span class="s">""</span>
    
    <span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
        <span class="kt">NavigationView</span><span class="p">(</span><span class="nv">content</span><span class="p">:</span> <span class="p">{</span>
            <span class="kt">VStack</span> <span class="p">{</span>
                <span class="kt">Text</span><span class="p">(</span><span class="s">"My name is </span><span class="se">\(</span><span class="n">myName</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
                
                <span class="kt">Button</span><span class="p">(</span><span class="s">"Change Name"</span><span class="p">)</span> <span class="p">{</span>
                    <span class="n">myName</span> <span class="o">=</span> <span class="s">"leo"</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">AppStore</code> 어노테이션을 추가하고 바로 다음에 오는 <code class="language-plaintext highlighter-rouge">"value"</code>는 <code class="language-plaintext highlighter-rouge">Key</code>값이 된다.
그리고 <code class="language-plaintext highlighter-rouge">var myName</code>은 변수의 이름이기 때문에 키 값과 동일할 필요는 없다.
앱을 실행하고 <code class="language-plaintext highlighter-rouge">Button</code>을 누른다음에 앱을 종료하고 다시 실행하면 <code class="language-plaintext highlighter-rouge">Text</code>가 <code class="language-plaintext highlighter-rouge">My name is leo</code>로 나오는 것을 확인할 수 있다.</p>]]></content><author><name></name></author><category term="SwiftUI" /><summary type="html"><![CDATA[Property Wrapper에 대해 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/SwiftUI.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/SwiftUI.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">UITableView Footer에서 Autolayout 사용하기</title><link href="https://lyfeoncloudnine.netlify.app/blog/footerview" rel="alternate" type="text/html" title="UITableView Footer에서 Autolayout 사용하기" /><published>2021-01-26T00:00:00+00:00</published><updated>2021-01-26T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/footerview</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/footerview"><![CDATA[<h3 id="uitableview에서의-footerview">UITableView에서의 FooterView</h3>

<p><code class="language-plaintext highlighter-rouge">UITableView</code>에서 <code class="language-plaintext highlighter-rouge">FooterView</code>를 사용할땐 frame 기반의 코드를 작성해야만 한다.
아마도 버그이지 않을까 싶지만, 언제나 그랬듯 개발자가 직접 수정해야만 한다.
먼저 어떻게 버그가 발생하는지 알아보자.</p>

<p><img src="/images/blog/21-01-26/01.png" /></p>

<p>우선 다음과 같이 커스텀 뷰를 만들고 오류가 나지 않도록 적절한 autolayout을 적용했다.
이제 이 커스텀 뷰를 <code class="language-plaintext highlighter-rouge">UITableView</code>에 <code class="language-plaintext highlighter-rouge">FooterView</code>로 지정해보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">ViewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="p">{</span>
    <span class="kd">@IBOutlet</span> <span class="kd">private</span> <span class="k">var</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="o">!</span>
    
    <span class="k">override</span> <span class="kd">func</span> <span class="nf">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">super</span><span class="o">.</span><span class="nf">viewDidLoad</span><span class="p">()</span>
        
        <span class="n">tableView</span><span class="o">.</span><span class="n">tableFooterView</span> <span class="o">=</span> <span class="kt">FooterView</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">ViewController</span><span class="p">:</span> <span class="kt">UITableViewDataSource</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="n">_</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">,</span> <span class="n">numberOfRowsInSection</span> <span class="nv">section</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span> <span class="p">{</span>
        <span class="mi">3</span>
    <span class="p">}</span>
    
    <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="n">_</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">,</span> <span class="n">cellForRowAt</span> <span class="nv">indexPath</span><span class="p">:</span> <span class="kt">IndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">UITableViewCell</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">cell</span> <span class="o">=</span> <span class="kt">UITableViewCell</span><span class="p">()</span>
        <span class="n">cell</span><span class="o">.</span><span class="n">textLabel</span><span class="p">?</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"</span><span class="se">\(</span><span class="n">indexPath</span><span class="se">)</span><span class="s">"</span>
        <span class="k">return</span> <span class="n">cell</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>간단한 코드라 코드에 대한 내용은 생략하고 바로 결과를 보자.</p>

<p><img src="/images/blog/21-01-26/02.png" /></p>

<p>자, 보다시피 완전히 망가져버렸다…
반면에 frame 기반으로 작성해보면 어떻게 될까</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">tableView</span><span class="o">.</span><span class="n">tableFooterView</span> <span class="o">=</span> <span class="kt">FooterView</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="kt">CGRect</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">width</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">frame</span><span class="o">.</span><span class="n">width</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="mi">250</span><span class="p">))</span>
</code></pre></div></div>

<p><img src="/images/blog/21-01-26/03.png" /></p>

<p>이처럼 frame에 기반한 코드로 처리하면 잘 나오게 된다.
그러나 만약 높이가 동적으로 변해야만 하는 뷰라면 어떻게 해야할까?</p>

<h3 id="동적으로-변하는-뷰에서-높이를-설정하는-방법">동적으로 변하는 뷰에서 높이를 설정하는 방법</h3>

<p>우선 이 방법도 frame에 기반한 코드이긴 하지만 높이를 수동으로 지정해주는 방법은 아니다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">override</span> <span class="kd">func</span> <span class="nf">viewDidLayoutSubviews</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">super</span><span class="o">.</span><span class="nf">viewDidLayoutSubviews</span><span class="p">()</span>
        
        <span class="k">guard</span> <span class="k">let</span> <span class="nv">footerView</span> <span class="o">=</span> <span class="n">tableView</span><span class="o">.</span><span class="n">tableFooterView</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
        <span class="k">let</span> <span class="nv">width</span> <span class="o">=</span> <span class="n">tableView</span><span class="o">.</span><span class="n">frame</span><span class="o">.</span><span class="n">width</span>
        <span class="k">let</span> <span class="nv">size</span> <span class="o">=</span> <span class="n">footerView</span><span class="o">.</span><span class="nf">systemLayoutSizeFitting</span><span class="p">(</span><span class="kt">CGSize</span><span class="p">(</span><span class="nv">width</span><span class="p">:</span> <span class="n">width</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="kt">UIView</span><span class="o">.</span><span class="n">layoutFittingCompressedSize</span><span class="o">.</span><span class="n">height</span><span class="p">))</span>
        <span class="k">guard</span> <span class="n">footerView</span><span class="o">.</span><span class="n">frame</span><span class="o">.</span><span class="n">height</span> <span class="o">!=</span> <span class="n">size</span><span class="o">.</span><span class="n">height</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
        <span class="n">footerView</span><span class="o">.</span><span class="n">frame</span><span class="o">.</span><span class="n">size</span><span class="o">.</span><span class="n">height</span> <span class="o">=</span> <span class="n">size</span><span class="o">.</span><span class="n">height</span>
<span class="p">}</span>
</code></pre></div></div>

<p>위와 같은 코드를 추가하게 되면 <code class="language-plaintext highlighter-rouge">FooterView</code>에 높이를 계산할 수 있고, 이를 다시 <code class="language-plaintext highlighter-rouge">FooterView</code>의 높이로 지정해주게 된다.
각 줄이 의미하는 코드는 쉬우므로 생략.
결과를 바로 보자.</p>

<p><img src="/images/blog/21-01-26/04.png" /></p>]]></content><author><name></name></author><category term="iOS" /><summary type="html"><![CDATA[UITableView의 Footer에서 Autolayout의 고장을 해결해봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/View.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/View.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">fastlane 배워보기 1탄</title><link href="https://lyfeoncloudnine.netlify.app/blog/fastlane1" rel="alternate" type="text/html" title="fastlane 배워보기 1탄" /><published>2020-02-27T00:00:00+00:00</published><updated>2020-02-27T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/fastlane1</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/fastlane1"><![CDATA[<h3 id="fastlane이란">fastlane이란?</h3>

<p>개발 외에 귀찮은 각종 테스트 빌드, 스크린샷, 배포 등을 손쉽게 도와주는 도구고, 이 글을 본다면 이미 <code class="language-plaintext highlighter-rouge">fastlane</code>이 뭔지는 알고 왔을테니 과감히 생략한다.
바로 실전 돌입</p>

<h3 id="fastlane-설치법">fastlane 설치법</h3>

<p>가장 먼저 <code class="language-plaintext highlighter-rouge">xcode select</code>를 설치해야 한다. 터미널에 다음을 입력하자.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xcode-select --install
</code></pre></div></div>

<p>그 다음은 난 <code class="language-plaintext highlighter-rouge">homebrew</code>를 이용할 것이다.
만약 <code class="language-plaintext highlighter-rouge">homebrew</code>가 안깔려있다면 설치하자.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
</code></pre></div></div>

<p>만약 이미 <code class="language-plaintext highlighter-rouge">homebrew</code>가 설치되어 있었다면 진행하기 전에 업데이트부터 하자.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>brew update
</code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">homebrew</code> 설치 및 최신화가 완료되었다면 이제 <code class="language-plaintext highlighter-rouge">fastlane</code>을 설치해보자.</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>brew install fastlane
</code></pre></div></div>

<p>짠 여기까지 fastlane 설치가 끝났다.</p>

<h3 id="fastlane으로-테스트를-해보자">fastlane으로 테스트를 해보자</h3>

<p>자 이제 <code class="language-plaintext highlighter-rouge">fastlane</code>을 이용할 프로젝트로 이동한 뒤 다음 명령어를 입력하자.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fastlane init
</code></pre></div></div>

<p><img src="/images/blog/20-02-27/01.png" /></p>

<p>그러면 다음과 같은 선택지가 나오고 아마 처음 설치한 경우에는 1, 2, 3 다 안될테고 4번을 선택해서 수동으로 세팅하자.
수동으로 해서 모든 과정이 끝나면 이제 fastlane을 이용한 테스트를 해보자.
먼저 테스트를 위해서는 <code class="language-plaintext highlighter-rouge">Fastfile</code>에 다음의 코드를 추가한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lane :tests do
  run_tests(scheme: "MyAppTests")
  end
</code></pre></div></div>

<p>참고로 “MyAppTests”는 내 앱의 scheme으로 변경해야한다.
또한, 당연히 프로젝트에 test 번들이 존재해야 한다.
나는 테스트를 위해 1개의 테스트 코드를 추가해둔 상태이고, 준비가 됐다면 <code class="language-plaintext highlighter-rouge">fastlane tests</code>를 입력해보자.</p>

<p><img src="/images/blog/20-02-27/02.png" /></p>

<p>짜잔 간단히 테스트가 끝나고 결과를 알려준다.
이번엔 테스트가 끝나면 슬랙의 특정 채널에 결과를 알려주도록 해보자.</p>

<p><a href="https://my.slack.com/services/new/incoming-webhook/">slack webhook url 만들기</a></p>

<p>위 주소로 접속해서 테스트 결과를 내보낼 채널의 url을 만들고, 아까 <code class="language-plaintext highlighter-rouge">Fastfile</code>에 추가한 코드를 수정해보자.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lane :tests do
  run_tests(scheme: "MyAppTests",
    slack_url: "https://hooks.slack.com/services/T03N...",
    slack_channel: "#channel")
	end
</code></pre></div></div>

<p>그리고 다시 <code class="language-plaintext highlighter-rouge">fastlane tests</code>를 입력해보면, 아까와 같이 테스트 결과가 나오고 슬랙에도 알려준다!!</p>

<p><img src="/images/blog/20-02-27/03.png" /></p>

<p>띠용…여기까지 일단 꿀이고요, 다른 기능은 다음편에서 계속 알아봅시다.</p>]]></content><author><name></name></author><category term="Library" /><summary type="html"><![CDATA[fastlane 사용법을 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/20-02-27/featured_image.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/20-02-27/featured_image.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">삼각형 그리기</title><link href="https://lyfeoncloudnine.netlify.app/blog/uibezierpath" rel="alternate" type="text/html" title="삼각형 그리기" /><published>2020-02-24T00:00:00+00:00</published><updated>2020-02-24T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/uibezierpath</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/uibezierpath"><![CDATA[<h3 id="삼각형-그리기">삼각형 그리기</h3>

<p>삼각형뿐 아니라 가장 기본적인 사각형, 원형 모두 <code class="language-plaintext highlighter-rouge">UIBezierPath</code>를 이용해서 직접 그릴 수 있다.
사각형, 원형은 사실 기본 <code class="language-plaintext highlighter-rouge">UIView</code>의 <code class="language-plaintext highlighter-rouge">layer</code>를 건드리면 쉽게 만들 수 있기 때문에 굳이 <code class="language-plaintext highlighter-rouge">UIBezierPath</code>를 쓸 필요는 없다.
하지만 삼각형이나 복잡한 모양의 도형을 만들 필요가 있는 경우 <code class="language-plaintext highlighter-rouge">UIBezierPath</code>를 사용해야 한다.
기본적인 순서는 원점을 정하고, 특정 좌표로 이동해 선을 긋고, 다시 원점으로 돌아오면 된다.
바로 시작해보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">CustomView</span><span class="p">:</span> <span class="kt">UIView</span> <span class="p">{</span>
    <span class="k">override</span> <span class="kd">func</span> <span class="nf">draw</span><span class="p">(</span><span class="n">_</span> <span class="nv">rect</span><span class="p">:</span> <span class="kt">CGRect</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">path</span> <span class="o">=</span> <span class="kt">UIBezierPath</span><span class="p">()</span>
        <span class="n">path</span><span class="o">.</span><span class="nf">move</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="kt">CGPoint</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">3</span><span class="p">))</span> <span class="c1">// 시작점을 (0, 3)으로 이동한다.</span>
        <span class="n">path</span><span class="o">.</span><span class="nf">addLine</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="kt">CGPoint</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">3</span><span class="p">))</span> <span class="c1">// (0, 30)에서 (100, 3)으로 이동한다.</span>
        <span class="n">path</span><span class="o">.</span><span class="nf">addLine</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="kt">CGPoint</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">120</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">100</span><span class="p">))</span> <span class="c1">// (100, 3)에서 (120, 100)으로 이동한다.</span>
        <span class="n">path</span><span class="o">.</span><span class="nf">close</span><span class="p">()</span> <span class="c1">// (120, 100)에서 시작점을 자동으로 연결한다.</span>
        <span class="n">path</span><span class="o">.</span><span class="n">lineWidth</span> <span class="o">=</span> <span class="mi">3</span> <span class="c1">// 선의 굵기를 3으로 지정한다.</span>
        
        <span class="kt">UIColor</span><span class="o">.</span><span class="n">black</span><span class="o">.</span><span class="nf">set</span><span class="p">()</span>
        <span class="n">path</span><span class="o">.</span><span class="nf">stroke</span><span class="p">()</span> <span class="c1">// 검은색으로 바탕을 채운다.</span>

        <span class="kt">UIColor</span><span class="o">.</span><span class="n">red</span><span class="o">.</span><span class="nf">set</span><span class="p">()</span>
        <span class="n">path</span><span class="o">.</span><span class="nf">fill</span><span class="p">()</span> <span class="c1">// 빨간색으로 채운다.</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>우선 이렇게 커스텀 뷰를 하나 만들었다.
그리고 이렇게 만들면</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">view</span> <span class="o">=</span> <span class="kt">CustomView</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="kt">CGRect</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nv">width</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="mi">200</span><span class="p">))</span>
<span class="n">view</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="kt">UIColor</span><span class="o">.</span><span class="n">blue</span>
<span class="k">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">view</span><span class="p">)</span>
</code></pre></div></div>

<p><img src="/images/blog/20-02-24/01.png" /></p>

<p>이런 결과가 나타난다.
시작점이 (0, 0)인 경우에 <code class="language-plaintext highlighter-rouge">lineWidth</code>값이 0보다 크게 되면 바깥으로 넘어갈 수 있어서 <code class="language-plaintext highlighter-rouge">lineWidth</code>값인 3만큼 시작점과 이후의 좌표를 조절했다.
이제 이걸로 뭘 할 수 있을까</p>

<h3 id="삼각형-응용해보기">삼각형 응용해보기</h3>

<p>이제 이걸로 <code class="language-plaintext highlighter-rouge">UIImageView</code>를 원하는대로 잘라볼 예정이다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">path</span> <span class="o">=</span> <span class="kt">UIBezierPath</span><span class="p">()</span>
<span class="n">path</span><span class="o">.</span><span class="nf">move</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="kt">CGPoint</span><span class="o">.</span><span class="n">zero</span><span class="p">)</span>
<span class="n">path</span><span class="o">.</span><span class="nf">addLine</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="kt">CGPoint</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">50</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">50</span><span class="p">))</span>
<span class="n">path</span><span class="o">.</span><span class="nf">addLine</span><span class="p">(</span><span class="nv">to</span><span class="p">:</span> <span class="kt">CGPoint</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">50</span><span class="p">))</span>
<span class="n">path</span><span class="o">.</span><span class="nf">close</span><span class="p">()</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">path</code>를 만들고 이제 이 <code class="language-plaintext highlighter-rouge">path</code>를 적용시켜보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">view</span> <span class="o">=</span> <span class="kt">UIImageView</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="kt">CGRect</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nv">width</span><span class="p">:</span> <span class="mi">50</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="mi">50</span><span class="p">))</span>
<span class="n">view</span><span class="o">.</span><span class="n">image</span> <span class="o">=</span> <span class="kt">UIImage</span><span class="p">(</span><span class="nv">named</span><span class="p">:</span> <span class="s">"아무사진.jpg"</span><span class="p">)</span>

<span class="k">let</span> <span class="nv">mask</span> <span class="o">=</span> <span class="kt">CAShapeLayer</span><span class="p">()</span>
<span class="n">mask</span><span class="o">.</span><span class="n">frame</span> <span class="o">=</span> <span class="n">view</span><span class="o">.</span><span class="n">bounds</span>
<span class="n">mask</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">cgPath</span>

<span class="n">view</span><span class="o">.</span><span class="n">layer</span><span class="o">.</span><span class="n">mask</span> <span class="o">=</span> <span class="n">mask</span>

<span class="k">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">view</span><span class="p">)</span>
</code></pre></div></div>

<p><img src="/images/blog/20-02-24/02.png" /></p>

<p>따란~
이런 식으로 원하는 도형을 그리면 된다.
참 쉽죠? 😎
선에 넓이를 주면 다양한 연출이 가능하다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">view</span> <span class="o">=</span> <span class="kt">UIImageView</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="kt">CGRect</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nv">width</span><span class="p">:</span> <span class="mi">50</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="mi">50</span><span class="p">))</span>
<span class="n">view</span><span class="o">.</span><span class="n">image</span> <span class="o">=</span> <span class="kt">UIImage</span><span class="p">(</span><span class="nv">named</span><span class="p">:</span> <span class="s">"아무사진.jpg"</span><span class="p">)</span>

<span class="k">let</span> <span class="nv">mask</span> <span class="o">=</span> <span class="kt">CAShapeLayer</span><span class="p">()</span>
<span class="n">mask</span><span class="o">.</span><span class="n">frame</span> <span class="o">=</span> <span class="n">view</span><span class="o">.</span><span class="n">bounds</span>
<span class="n">mask</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">cgPath</span>
<span class="n">mask</span><span class="o">.</span><span class="n">strokeColor</span> <span class="o">=</span> <span class="kt">UIColor</span><span class="o">.</span><span class="n">black</span><span class="o">.</span><span class="n">cgColor</span>
<span class="n">mask</span><span class="o">.</span><span class="n">lineWidth</span> <span class="o">=</span> <span class="mi">25</span>

<span class="n">view</span><span class="o">.</span><span class="n">layer</span><span class="o">.</span><span class="n">mask</span> <span class="o">=</span> <span class="n">mask</span>

<span class="k">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">view</span><span class="p">)</span>
</code></pre></div></div>

<p><img src="/images/blog/20-02-24/03.png" /></p>

<p>따란~
넓이를 지정하면서 위 사진같은 모양도 얼마든지 만들 수 있다.
끝~</p>]]></content><author><name></name></author><category term="iOS" /><summary type="html"><![CDATA[Swift로 삼각형을 그리는 방법을 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/View.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/View.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">버블 정렬과 선택 정렬</title><link href="https://lyfeoncloudnine.netlify.app/blog/sort-algorithm-1" rel="alternate" type="text/html" title="버블 정렬과 선택 정렬" /><published>2020-02-08T00:00:00+00:00</published><updated>2020-02-08T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/sort-algorithm-1</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/sort-algorithm-1"><![CDATA[<h3 id="버블-정렬">버블 정렬</h3>

<p>버블 정렬은 인접한 값을 비교해서 더 큰 수를 뒤로 보내 정렬하는 알고리즘이다.
원리 자체가 굉장히 간단하기 때문에 구현도 간편하지만, 시간 복잡도가 O(N^2) 이기 때문에 성능은 떨어진다.
시간 복잡도가 O(N^2)인 이유는 배열의 모든 요소를 한번씩 비교하면서 교환까지 이루어지기 때문이다.
버블 정렬을 Swift로 구현하자면 다음과 같다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">bubbleSort</span><span class="p">(</span><span class="nv">arr</span><span class="p">:</span> <span class="p">[</span><span class="kt">Int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="kt">Int</span><span class="p">]</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">arr</span> <span class="o">=</span> <span class="n">arr</span>
    <span class="k">var</span> <span class="nv">totalLength</span> <span class="o">=</span> <span class="n">arr</span><span class="o">.</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span>
    
    <span class="k">while</span> <span class="n">totalLength</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">{</span>
        <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">0</span><span class="o">...</span><span class="n">totalLength</span> <span class="p">{</span>
            <span class="k">let</span> <span class="nv">nextIndex</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
            <span class="k">if</span> <span class="n">nextIndex</span> <span class="o">&lt;=</span> <span class="n">totalLength</span> <span class="p">{</span>
                <span class="k">if</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">arr</span><span class="p">[</span><span class="n">nextIndex</span><span class="p">]</span> <span class="p">{</span>
                    <span class="k">let</span> <span class="nv">small</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">nextIndex</span><span class="p">]</span>
                    <span class="n">arr</span><span class="p">[</span><span class="n">nextIndex</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
                    <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">small</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="n">nextIndex</span> <span class="o">==</span> <span class="n">totalLength</span> <span class="p">{</span>
                    <span class="n">totalLength</span> <span class="o">-=</span> <span class="mi">1</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="n">arr</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="선택-정렬">선택 정렬</h3>

<p>선택 정렬은 배열의 모든 요소를 비교하면서 가장 작은 수를 가장 앞으로 보내어 정렬하는 알고리즘이다.
버블 정렬과 마찬가지로 배열의 모든 요소를 비교하지만, 교환은 단 한번만 이루어진다.
그래서 버블 정렬보다 우위에 있지만 빅 오 표기법상 상수를 무시하여 같은 O(N^2) 시간 복잡도를 가진다.
Swift로 구현하면 다음과 같다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">selectionSort</span><span class="p">(</span><span class="nv">arr</span><span class="p">:</span> <span class="p">[</span><span class="kt">Int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="kt">Int</span><span class="p">]</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">arr</span> <span class="o">=</span> <span class="n">arr</span>
    
    <span class="k">var</span> <span class="nv">startPosition</span> <span class="o">=</span> <span class="mi">0</span>
    
    <span class="k">while</span> <span class="n">startPosition</span> <span class="o">!=</span> <span class="p">(</span><span class="n">arr</span><span class="o">.</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">lowerNumberIndex</span><span class="p">:</span> <span class="kt">Int</span><span class="o">!</span>
        
        <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="n">startPosition</span><span class="o">...</span><span class="p">(</span><span class="n">arr</span><span class="o">.</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="n">startPosition</span> <span class="p">{</span>
                <span class="n">lowerNumberIndex</span> <span class="o">=</span> <span class="n">i</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="k">if</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="p">[</span><span class="n">lowerNumberIndex</span><span class="p">]</span> <span class="p">{</span>
                    <span class="n">lowerNumberIndex</span> <span class="o">=</span> <span class="n">i</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="p">(</span><span class="n">arr</span><span class="o">.</span><span class="n">count</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">let</span> <span class="nv">temp</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">startPosition</span><span class="p">]</span>
                    <span class="n">arr</span><span class="p">[</span><span class="n">startPosition</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">lowerNumberIndex</span><span class="p">]</span>
                    <span class="n">arr</span><span class="p">[</span><span class="n">lowerNumberIndex</span><span class="p">]</span> <span class="o">=</span> <span class="n">temp</span>
                    <span class="n">startPosition</span> <span class="o">+=</span> <span class="mi">1</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="n">arr</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="Algorithm" /><category term="Swift" /><summary type="html"><![CDATA[버블 정렬과 선택 정렬을 Swift로 구현해봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/Swift.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/Swift.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">RxSwift의 Sharing Operator</title><link href="https://lyfeoncloudnine.netlify.app/blog/sharingoperator" rel="alternate" type="text/html" title="RxSwift의 Sharing Operator" /><published>2019-12-17T00:00:00+00:00</published><updated>2019-12-17T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/sharingoperator</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/sharingoperator"><![CDATA[<h3 id="사용-목적">사용 목적</h3>

<p>서로 공유되지 않는 개별적인 Sequence를 공유하여 한번만 실행하도록 한다.
네트워크 요청이나 DB에 접근하는 작업에 유용하다.</p>

<h3 id="multicast">multicast</h3>

<p><code class="language-plaintext highlighter-rouge">multicasst(_:)</code> 연산자는 <code class="language-plaintext highlighter-rouge">Subject</code>를 파라미터로 받는데, 원본 <code class="language-plaintext highlighter-rouge">Observerble</code>에서 방출되는 이벤트가 구독자에게 바로 전달되는 것이 아니라 파라미터로 전달된 <code class="language-plaintext highlighter-rouge">Subject</code>에게 전달된다.
그리고 이 <code class="language-plaintext highlighter-rouge">Subject</code>가 등록된 다수의 구독자에게 이벤트를 전달한다.
여기에서 <code class="language-plaintext highlighter-rouge">ConnectableObservable이</code> 등장하는데, 구독이 시작되면 이벤트를 바로 전달하는 일반 <code class="language-plaintext highlighter-rouge">Observable</code>과 달리 <code class="language-plaintext highlighter-rouge">connect()</code> 메소드가 실행되어야 이벤트를 방출한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">subject</span> <span class="o">=</span> <span class="kt">PublishSubject</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;</span><span class="p">()</span>

<span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔵</span> <span class="n">completed</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔴</span> <span class="n">completed</span>
</code></pre></div></div>

<p>여기에서 <code class="language-plaintext highlighter-rouge">multicast(_:)</code> 연산자를 추가하면, 아무일도 발생하지 않는다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">subject</span> <span class="o">=</span> <span class="kt">PublishSubject</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;</span><span class="p">()</span>

<span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="nf">multicast</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span> <span class="c1">// 추가</span>

<span class="n">source</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
   <span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>
</code></pre></div></div>

<p>왜냐하면 <code class="language-plaintext highlighter-rouge">connect()</code>가 호출되지 않았기 때문이다.
아래처럼 <code class="language-plaintext highlighter-rouge">connect()</code>를 호출하게 되면 결과는 다음과 같다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">subject</span> <span class="o">=</span> <span class="kt">PublishSubject</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;</span><span class="p">()</span>

<span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="nf">multicast</span><span class="p">(</span><span class="n">subject</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span><span class="o">.</span><span class="nf">connect</span><span class="p">()</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔵</span> <span class="n">completed</span>
<span class="n">🔴</span> <span class="n">completed</span>
</code></pre></div></div>

<p>결과를 보면 두번째 구독자는 0부터 받지 않고 2부터 받는다.
이전에는 각 구독자마다 개별 Sequence이기 때문에 처음부터 방출되는 값을 받지만, 이제는 같은 <code class="language-plaintext highlighter-rouge">Subject</code>를 공유하기 때문에 두번째 구독자는 3초가 지난 시점부터 방출된 이벤트를 처리할 수 있는 것이다.</p>

<h3 id="publish">publish</h3>

<p><code class="language-plaintext highlighter-rouge">multicast(_:)</code>와 똑같은 기능을 하지만 연산자 내부에서 <code class="language-plaintext highlighter-rouge">Subject</code>를 생성하기 때문에 별도의 파라미터 없이 간단히 구현이 가능하다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">bag</span> <span class="o">=</span> <span class="kt">DisposeBag</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="nf">publish</span><span class="p">()</span>

<span class="n">source</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span><span class="o">.</span><span class="nf">connect</span><span class="p">()</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔵</span> <span class="n">completed</span>
<span class="n">🔴</span> <span class="n">completed</span>
</code></pre></div></div>

<h3 id="replay">replay</h3>

<p>지금까지처럼 구독을 지연시킨 경우 <code class="language-plaintext highlighter-rouge">Subject</code>를 공유하기 때문에 두번째 구독은 일부 이벤트를 놓치게 된다.
이런 경우에 만약 두번째 구독자도 모든 이벤트를 받고자 한다면 이 연산자를 사용한다.
이 연산자는 내부적으로 <code class="language-plaintext highlighter-rouge">Publish()</code> 연산자와 동일하지만, 내부에서 생성되는 <code class="language-plaintext highlighter-rouge">Subject</code>가 <code class="language-plaintext highlighter-rouge">PublishSubject</code>가 아닌 <code class="language-plaintext highlighter-rouge">ReplaySubject</code>이기 때문에 <code class="language-plaintext highlighter-rouge">buffer</code>를 활용할 수 있다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">bag</span> <span class="o">=</span> <span class="kt">DisposeBag</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="nf">replay</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span>
	<span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
	<span class="o">.</span><span class="nf">disposed</span><span class="p">(</span><span class="nv">by</span><span class="p">:</span> <span class="n">bag</span><span class="p">)</span>

<span class="n">source</span><span class="o">.</span><span class="nf">connect</span><span class="p">()</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔵</span> <span class="n">completed</span>
<span class="n">🔴</span> <span class="n">completed</span>
</code></pre></div></div>

<p>이는 <code class="language-plaintext highlighter-rouge">multicast(_:)</code> 연산자에 직접 <code class="language-plaintext highlighter-rouge">ReplaySubject</code>를 전달한 것과 똑같다.</p>

<h3 id="refcount">refCount</h3>

<p>지금까지의 Sharing Operator는 모두 <code class="language-plaintext highlighter-rouge">ObservableType</code>에 구현되어 있지만, <code class="language-plaintext highlighter-rouge">refCount</code>의 경우는 <code class="language-plaintext highlighter-rouge">ConnectableObservableType</code>에 구현되어 있기 때문에 <code class="language-plaintext highlighter-rouge">ConnectableObservable</code>에서만 사용할 수 있다.
아래의 코드에서는 <code class="language-plaintext highlighter-rouge">connect()</code> 메서드가 실행되면서 끊임없이 이벤트를 방출하게 된다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">bag</span> <span class="o">=</span> <span class="kt">DisposeBag</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">debug</span><span class="p">()</span><span class="o">.</span><span class="nf">publish</span><span class="p">()</span>

<span class="k">let</span> <span class="nv">observer1</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="n">source</span><span class="o">.</span><span class="nf">connect</span><span class="p">()</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">observer1</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
<span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">observer2</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
    
    <span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">observer2</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="mf">57.836</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="mf">58.851</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span><span class="mf">59.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">00.851</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">01.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">02.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">03.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">04.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">05.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">06.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">07.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">08.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">09.851</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">10.852</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">11.851</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">12.851</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">14</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">29</span><span class="p">:</span><span class="mf">13.851</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_31</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">15</span><span class="p">)</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
</code></pre></div></div>

<p>반면 <code class="language-plaintext highlighter-rouge">refCount()</code> 메서드는 구독이 시작되면 내부적으로 <code class="language-plaintext highlighter-rouge">connect()</code> 메서드를 호출하기 때문에 명시적으로 <code class="language-plaintext highlighter-rouge">connect()</code> 메서드를 호출할 수 없다.
또한 구독자가 없으면 자동으로 이벤트는 중지된다.
새로운 구독자가 생기면 Sequence를 다시 시작한다.
직접 <code class="language-plaintext highlighter-rouge">dispose()</code>를 호출하거나, <code class="language-plaintext highlighter-rouge">take(_:)</code> 연산자 등을 통해 직접 관리해야할 부분을 알아서 해준다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">bag</span> <span class="o">=</span> <span class="kt">DisposeBag</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">debug</span><span class="p">()</span><span class="o">.</span><span class="nf">publish</span><span class="p">()</span><span class="o">.</span><span class="nf">refCount</span><span class="p">()</span>

<span class="k">let</span> <span class="nv">observer1</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">observer1</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
<span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">observer2</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
    
    <span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">observer2</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">28.986</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">29.989</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">30.989</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">31.989</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">32.282</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">36.699</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">37.699</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">38.700</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">39.699</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mf">39.993</span><span class="p">:</span> <span class="n">refCount</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_33</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
</code></pre></div></div>

<h3 id="share">share</h3>

<p>이 연산자는 <code class="language-plaintext highlighter-rouge">multicast(_:)</code> 연산자와 <code class="language-plaintext highlighter-rouge">refCount()</code>를 합친 종합 선물과도 같은 연산자이다.
이 연산자는 2개의 파라미터를 받는데 첫째는 replay는 기본값이 0으로, 0보다 크다면 <code class="language-plaintext highlighter-rouge">multicast(_:)</code> 내부에서 <code class="language-plaintext highlighter-rouge">ReplaySubject</code>를 생성하므로 <code class="language-plaintext highlighter-rouge">replay(_:)</code> 연산자와 같고, 기본값이라면 내부에서 <code class="language-plaintext highlighter-rouge">PublishSubject</code>를 생성하므로 <code class="language-plaintext highlighter-rouge">publish()</code> 연산자와 같다.
두번째 파라미터인 scope는 생명주기로 <code class="language-plaintext highlighter-rouge">.whileConnected</code>를 택하면 <code class="language-plaintext highlighter-rouge">refCount()</code> 처럼 구독이 시작되면 <code class="language-plaintext highlighter-rouge">connect()</code> 되었다가 구독이 끝나면 끝이나고, 반면 <code class="language-plaintext highlighter-rouge">.forever</code>를 택하면 <code class="language-plaintext highlighter-rouge">multicast(_:)</code> 연산자처럼 하나의 <code class="language-plaintext highlighter-rouge">Subject</code>를 공유한다. 기본값은 <code class="language-plaintext highlighter-rouge">.whileConnected</code>다.
하나씩 살펴보자</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">debug</span><span class="p">()</span><span class="o">.</span><span class="nf">share</span><span class="p">()</span>

<span class="k">let</span> <span class="nv">observer1</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="k">let</span> <span class="nv">observer2</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">observer1</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="n">observer2</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
<span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">observer3</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"⚫️"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
    
    <span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">observer3</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>위처럼 파라미터없이 호출하게되는 경우에는 <code class="language-plaintext highlighter-rouge">publish()</code>와 <code class="language-plaintext highlighter-rouge">refCount()</code>의 조합이다.
따라서 <code class="language-plaintext highlighter-rouge">observer2</code>는 3초 지연된 시점부터 이벤트를 처리할 수 있고, <code class="language-plaintext highlighter-rouge">observer3</code>은 <code class="language-plaintext highlighter-rouge">connect()</code>된 시점인 7초 후 부터 새로운 Sequence를 받는다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">05.094</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">06.098</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">07.098</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">08.097</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">09.098</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">10.097</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">10.609</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">12.809</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">13.809</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">14.809</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">15.809</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">14</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="mf">16.103</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">31</span> <span class="p">(</span><span class="n">__lldb_expr_37</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>

</code></pre></div></div>

<p>이제 <code class="language-plaintext highlighter-rouge">replay</code> 값을 추가해보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">debug</span><span class="p">()</span><span class="o">.</span><span class="nf">share</span><span class="p">(</span><span class="nv">replay</span><span class="p">:</span> <span class="mi">5</span><span class="p">)</span>

<span class="k">let</span> <span class="nv">observer1</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="k">let</span> <span class="nv">observer2</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">observer1</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="n">observer2</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
<span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">observer3</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"⚫️"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
    
    <span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">observer3</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">14.376</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">15.392</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">16.386</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">17.387</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">18.386</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">19.387</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">19.878</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">22.079</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">23.080</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">24.079</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">25.080</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="mf">25.360</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_39</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
</code></pre></div></div>

<p>결과를 보면, 이벤트가 <code class="language-plaintext highlighter-rouge">buffer</code>에 저장되기 때문에 <code class="language-plaintext highlighter-rouge">observer2</code>도 0부터 이벤트를 받을 수 있다.
하지만 <code class="language-plaintext highlighter-rouge">observer3</code>은 새로운 Sequence이기 때문에 구독시점에 하나의 이벤트만 받을 수 있다.
마지막으로 생명주기를 바꿔보자.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">source</span> <span class="o">=</span> <span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span><span class="o">.</span><span class="nf">debug</span><span class="p">()</span><span class="o">.</span><span class="nf">share</span><span class="p">(</span><span class="nv">replay</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="nv">scope</span><span class="p">:</span> <span class="o">.</span><span class="n">forever</span><span class="p">)</span>

<span class="k">let</span> <span class="nv">observer1</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔵"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="k">let</span> <span class="nv">observer2</span> <span class="o">=</span> <span class="n">source</span>
    <span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🔴"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">observer1</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="n">observer2</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
<span class="p">}</span>

<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">observer3</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"⚫️"</span><span class="p">,</span> <span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
    
    <span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="nf">asyncAfter</span><span class="p">(</span><span class="nv">deadline</span><span class="p">:</span> <span class="o">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">observer3</span><span class="o">.</span><span class="nf">dispose</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">14.702</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">15.705</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">16.704</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">17.705</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">18.704</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">19.705</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔵</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">🔴</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">20.230</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">22.433</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">23.434</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">24.434</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">25.433</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="err">⚫️</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">17</span> <span class="mi">15</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mf">25.733</span><span class="p">:</span> <span class="n">share</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">30</span> <span class="p">(</span><span class="n">__lldb_expr_41</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">observer3</code>의 결과가 조금 이상하다.
<code class="language-plaintext highlighter-rouge">buffer</code>로 지정된 만큼 이벤트를 받지만, 이후부터는 다시 0부터 이벤트를 받는다.
헷갈리면 안될 개념으로 <code class="language-plaintext highlighter-rouge">Subject</code>를 공유하는 것일뿐 Sequence를 공유하는 것이 아니다.
다시 정리하자면 <code class="language-plaintext highlighter-rouge">refCount()</code>는 새로운 구독자가 생기면 <code class="language-plaintext highlighter-rouge">connect()</code>를 호출하여 <code class="language-plaintext highlighter-rouge">Subject</code>가 생성된다.
그래서 <code class="language-plaintext highlighter-rouge">connect()</code> 마다 새로운 <code class="language-plaintext highlighter-rouge">Subject</code>가 생성된다.
그런데 <code class="language-plaintext highlighter-rouge">.forever</code>의 경우 새로운 <code class="language-plaintext highlighter-rouge">Subject</code>가 생성되는 것은 아니고 기존 <code class="language-plaintext highlighter-rouge">Subject</code>를 공유하지만, Sequence가 유지되는 것은 아니기 때문에 이 같은 결과가 나온다.</p>]]></content><author><name></name></author><category term="RxSwift" /><summary type="html"><![CDATA[RxSwift의 Sharing Operator에 대해서 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/RxSwift.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/RxSwift.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">RxSwift의 Time-based Operator</title><link href="https://lyfeoncloudnine.netlify.app/blog/timebasedoperator" rel="alternate" type="text/html" title="RxSwift의 Time-based Operator" /><published>2019-12-13T00:00:00+00:00</published><updated>2019-12-13T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/timebasedoperator</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/timebasedoperator"><![CDATA[<h3 id="interval">interval</h3>

<p>특정 주기마다 정수를 방출하는 <code class="language-plaintext highlighter-rouge">Observable</code>을 생성하고 싶을 때 사용한다.
첫번째 파라미터로 방출 주기를 정하고, 두번째 파라미터에 스케줄러를 전달한다.
구독할때 방출이 시작되므로 새로운 구독자가 추가될때마다 타이머가 개별로 실행된다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span> <span class="c1">// next(0) -&gt; next(1) -&gt; next(2)...</span>
</code></pre></div></div>

<h3 id="timer">timer</h3>

<p><code class="language-plaintext highlighter-rouge">interval(_:scheduler:)</code>처럼 특정 주기마다 정수를 방출하지만 지연시간에 따라 동작방식이 달라진다.
지연시간은 구독이 시작되고 지연시간만큼 지난 뒤 방출이 시작도록 한다.
또 <code class="language-plaintext highlighter-rouge">period</code>의 경우 optional인데, 만약 생략할 경우 하나의 이벤트만 방출하고 종료된다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">timer</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">period</span><span class="p">:</span> <span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span> <span class="c1">// 3초 후 next(0) -&gt; next(1) -&gt; next(2)...</span>
</code></pre></div></div>

<h3 id="timeout">timeout</h3>

<p>첫번째 파라미터로 전달되는 시간동안 새로운 이벤트가 방출되지 않으면 에러 이벤트가 방출된다.
반대로 이 시간안에 새로운 이벤트가 방출되면 그대로 전달된다.
<code class="language-plaintext highlighter-rouge">other</code> 파라미터에는 지정된 시간동안 새로운 이벤트를 방출하지 않은 경우 새롭게 구독할 구독자를 입력한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">subject</span> <span class="o">=</span> <span class="kt">PublishSubject</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;</span><span class="p">()</span>

<span class="n">subject</span><span class="o">.</span><span class="nf">timeout</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span> <span class="c1">// next(0) -&gt; error(Sequence timeout.)</span>

<span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">timer</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">period</span><span class="p">:</span> <span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="nf">subscribe</span><span class="p">(</span><span class="nv">onNext</span><span class="p">:</span> <span class="p">{</span> <span class="n">subject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">})</span>

<span class="k">let</span> <span class="nv">subject2</span> <span class="o">=</span> <span class="kt">PublishSubject</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;</span><span class="p">()</span>

<span class="n">subject2</span><span class="o">.</span><span class="nf">timeout</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="nv">other</span><span class="p">:</span> <span class="kt">Observable</span><span class="o">.</span><span class="nf">just</span><span class="p">(</span><span class="mi">100</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span> <span class="c1">// next(100) -&gt; completed</span>

<span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="nf">subscribe</span><span class="p">(</span><span class="nv">onNext</span><span class="p">:</span> <span class="p">{</span> <span class="n">subject2</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">})</span>
</code></pre></div></div>

<h3 id="delay">delay</h3>

<p>구독자에게 전달될 이벤트를 지정된 시간만큼 지연시킨다.
에러의 경우 지연없이 즉시 전달된다.
구독 자체를 지연하는 것이 아니라 이벤트 전달만 지연한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
	<span class="o">.</span><span class="nf">debug</span><span class="p">()</span>
	<span class="o">.</span><span class="nf">delay</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">55</span><span class="p">:</span><span class="mf">55.164</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">55</span><span class="p">:</span><span class="mf">56.270</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">55</span><span class="p">:</span><span class="mf">57.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">55</span><span class="p">:</span><span class="mf">58.270</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">55</span><span class="p">:</span><span class="mf">59.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">00.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">01.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">02.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">03.270</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">04.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">05.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">05.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="n">completed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mf">05.269</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">28</span> <span class="p">(</span><span class="n">__lldb_expr_9</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span>
<span class="n">completed</span>
</code></pre></div></div>

<h3 id="delaysubscription">delaySubscription</h3>

<p><code class="language-plaintext highlighter-rouge">delay(_:scheduler:)</code>와 달리 구독 자체를 지연시키고 싶은 경우에 사용한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">Observable</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">interval</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="nf">take</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
	<span class="o">.</span><span class="nf">debug</span><span class="p">()</span>
	<span class="o">.</span><span class="nf">delaySubscription</span><span class="p">(</span><span class="o">.</span><span class="nf">seconds</span><span class="p">(</span><span class="mi">7</span><span class="p">),</span> <span class="nv">scheduler</span><span class="p">:</span> <span class="kt">MainScheduler</span><span class="o">.</span><span class="n">instance</span><span class="p">)</span>
	<span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mf">58.423</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">subscribed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mf">59.427</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">00.427</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">01.427</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">02.427</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">03.428</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">04.427</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">05.429</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">06.428</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">07.429</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">08.428</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="nf">next</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span>
<span class="nf">next</span><span class="p">(</span><span class="mi">9</span><span class="p">)</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">08.429</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Event</span> <span class="n">completed</span>
<span class="n">completed</span>
<span class="mi">2019</span><span class="o">-</span><span class="mi">12</span><span class="o">-</span><span class="mi">13</span> <span class="mi">17</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mf">08.429</span><span class="p">:</span> <span class="kt">Hello</span><span class="o">.</span><span class="nv">playground</span><span class="p">:</span><span class="mi">37</span> <span class="p">(</span><span class="n">__lldb_expr_11</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">isDisposed</span>

</code></pre></div></div>]]></content><author><name></name></author><category term="RxSwift" /><summary type="html"><![CDATA[RxSwift의 Time-based Operator에 대해서 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/RxSwift.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/RxSwift.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">RxSwift의 Conditional Operator</title><link href="https://lyfeoncloudnine.netlify.app/blog/conditionaloperator" rel="alternate" type="text/html" title="RxSwift의 Conditional Operator" /><published>2019-12-12T00:00:00+00:00</published><updated>2019-12-12T00:00:00+00:00</updated><id>https://lyfeoncloudnine.netlify.app/blog/conditionaloperator</id><content type="html" xml:base="https://lyfeoncloudnine.netlify.app/blog/conditionaloperator"><![CDATA[<h3 id="amb">amb</h3>

<p>가장 먼저 이벤트를 방출하는 <code class="language-plaintext highlighter-rouge">Observable</code>을 구독하고, 나머지는 무시한다.
기본적인 구현은 다음과 같다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">aSubject</span> <span class="o">=</span> <span class="kt">PublishSubject</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">init</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">bSubject</span> <span class="o">=</span> <span class="kt">PublishSubject</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;.</span><span class="nf">init</span><span class="p">()</span>

<span class="n">aSubject</span><span class="o">.</span><span class="nf">amb</span><span class="p">(</span><span class="n">bSubject</span><span class="p">)</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="n">bSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1">// next(0)</span>
<span class="n">aSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1">// 무시</span>
<span class="n">aSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c1">// 무시</span>
<span class="n">bSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="c1">// next(3)</span>
</code></pre></div></div>

<p>만약 2개 이상의 <code class="language-plaintext highlighter-rouge">Observable</code>을 비교하고 싶다면 타입 메서드로 구현된 <code class="language-plaintext highlighter-rouge">amb(_:)</code> 연산자를 사용해야 한다.
그리고 전달되는 <code class="language-plaintext highlighter-rouge">Observable</code>은 배열로 전달해야 한다.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">MyError</span><span class="p">:</span> <span class="kt">Error</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">error</span>
<span class="p">}</span>

<span class="kt">Observable</span><span class="o">.</span><span class="nf">amb</span><span class="p">([</span><span class="n">aSubject</span><span class="p">,</span> <span class="n">bSubject</span><span class="p">,</span> <span class="n">cSubject</span><span class="p">])</span>
    <span class="o">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)</span> <span class="p">}</span>

<span class="n">cSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1">// next(0)</span>
<span class="n">aSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1">// 무시</span>
<span class="n">aSubject</span><span class="o">.</span><span class="nf">onError</span><span class="p">(</span><span class="kt">MyError</span><span class="o">.</span><span class="n">error</span><span class="p">)</span> <span class="c1">// 무시</span>
<span class="n">bSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c1">// 무시</span>
<span class="n">bSubject</span><span class="o">.</span><span class="nf">onCompleted</span><span class="p">()</span> <span class="c1">// 무시</span>
<span class="n">cSubject</span><span class="o">.</span><span class="nf">onNext</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="c1">// next(3)</span>
<span class="n">cSubject</span><span class="o">.</span><span class="nf">onCompleted</span><span class="p">()</span> <span class="c1">// completed</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="RxSwift" /><summary type="html"><![CDATA[RxSwift의 Conditional Operator에 대해서 알아봅니다.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lyfeoncloudnine.netlify.app/images/blog/RxSwift.png" /><media:content medium="image" url="https://lyfeoncloudnine.netlify.app/images/blog/RxSwift.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>