<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://ga-yo.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ga-yo.github.io/" rel="alternate" type="text/html" /><updated>2021-08-05T02:11:34+00:00</updated><id>https://ga-yo.github.io/feed.xml</id><title type="html">Ga-yo’s</title><subtitle>An amazing website.</subtitle><author><name>Gayo</name></author><entry><title type="html">iOS 레이아웃의 모든 것 (레이아웃 종류와 레이아웃 사이클</title><link href="https://ga-yo.github.io/view/iOS-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83-(%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%A2%85%EB%A5%98%EC%99%80-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%82%AC%EC%9D%B4%ED%81%B4)/" rel="alternate" type="text/html" title="iOS 레이아웃의 모든 것 (레이아웃 종류와 레이아웃 사이클" /><published>2021-08-04T16:27:34+00:00</published><updated>2021-08-04T16:27:34+00:00</updated><id>https://ga-yo.github.io/view/iOS%20%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83%EC%9D%98%20%EB%AA%A8%EB%93%A0%20%EA%B2%83%20(%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83%20%EC%A2%85%EB%A5%98%EC%99%80%20%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83%20%EC%82%AC%EC%9D%B4%ED%81%B4)</id><content type="html" xml:base="https://ga-yo.github.io/view/iOS-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83-(%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%A2%85%EB%A5%98%EC%99%80-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EC%82%AC%EC%9D%B4%ED%81%B4)/">&lt;h3 id=&quot;ios에서-레이아웃을-접근하는-방법-3가지&quot;&gt;iOS에서 레이아웃을 접근하는 방법 3가지&lt;/h3&gt;

&lt;p&gt;iOS에서 레이아웃을 구성할 때 접근하는 방법이 3가지가 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;h4 id=&quot;frame-기반의-프로그래밍-방식&quot;&gt;&lt;strong&gt;Frame 기반의 프로그래밍 방식&lt;/strong&gt;&lt;/h4&gt;

    &lt;ul&gt;
      &lt;li&gt;가장 유연하고 성능 빠름&lt;/li&gt;
      &lt;li&gt;모든 뷰에 개별적인 설정과 관리 필요&lt;/li&gt;
      &lt;li&gt;설계 및 디버그나 유지관리에 많은 노력 필요&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;h4 id=&quot;autoresizing-masks&quot;&gt;&lt;strong&gt;Autoresizing masks&lt;/strong&gt;&lt;/h4&gt;

    &lt;ul&gt;
      &lt;li&gt;Frame 기반에서 한층 성장한 방법&lt;/li&gt;
      &lt;li&gt;복잡한 UI를 구현하기 어려워 AutoLayout 도입&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;h4 id=&quot;autolayout&quot;&gt;&lt;strong&gt;AutoLayout&lt;/strong&gt;&lt;/h4&gt;

    &lt;ul&gt;
      &lt;li&gt;제약조건을 이용해 유저 인터페이스 정의&lt;/li&gt;
      &lt;li&gt;뷰간의 관계 설정을 통해 크기와 위치 계산&lt;/li&gt;
      &lt;li&gt;Frame기반보다 느린 퍼포먼스&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;view-layout-cycle&quot;&gt;View Layout Cycle&lt;/h3&gt;

&lt;p&gt;Layout을 구성하는 다양한 방법은 위에서 본 바와 같다. 위의 3가지로 Layout을 구성할 수 있는데 iPhoneX 시리즈의 노치디자인에 대응하기 위해선 Frame 기반보다 AutoLayout 기반이 더욱 효율적이다. 그렇다면 이미 Frame 기반으로 배포된 앱을 AutoLayout으로 변경할 때 뷰 레이아웃 사이클이 필요하다.&lt;/p&gt;

&lt;h4 id=&quot;view를-그리는-3가지-단계&quot;&gt;View를 그리는 3가지 단계&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;Constraint Update
    &lt;ul&gt;
      &lt;li&gt;AutoLayout의 제약을 갱신한다&lt;/li&gt;
      &lt;li&gt;subview -&amp;gt; superview 순서대로 호출된다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Layout Update
    &lt;ul&gt;
      &lt;li&gt;구체적인 뷰의 수치값 업데이트&lt;/li&gt;
      &lt;li&gt;View의 Center, Bounds를 결정한다&lt;/li&gt;
      &lt;li&gt;superview -&amp;gt; subview 순서대로 호출된다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Render
    &lt;ul&gt;
      &lt;li&gt;UIView의 &lt;code&gt;drawRect:&lt;/code&gt;가 호출되면 뷰를 그린다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;constraint&quot;&gt;Constraint&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;업데이트 :&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;updateConstraints&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;보통 View의 Constraints를 동적으로 변경할 때 구현한다.&lt;/p&gt;

    &lt;p&gt;subview에서 superview 순서로 호출되기 때문에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super.updateConstraints&lt;/code&gt;는 가장 마지막에 호출된다 만약 뷰의 제약을 갱신하고 싶다고해도 &lt;strong&gt;코드로 직접 호출해선 안된다&lt;/strong&gt;. 시스템이 적절한 타이밍에 호출해주기 때문이다.&lt;/p&gt;

    &lt;p&gt;시스템에 뷰의 제약 갱신을 요청하기 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setNeedsUpdateConstraints&lt;/code&gt; 라는 메소드를 호출할 수 있다 이 함수 호출을 통해 제약의 갱신을 해야한다는 플래그를 표시한다 그 플래그를 보고 시스템이 처리하게된다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;플래그를 심는다는 것은 한번의 RunLoop가 끝나고 다음 RunLoop를 실행할 때 View의 플래그를 보고 한번에 모든 View를 갱신하는 방법을 뜻한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;플래그 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setNeedsUpdateConstraints&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;이 메소드를 실행하게 되면 갱신을 하지 않고 시스템이 한번에 갱신을 실행한다 updateConstraints를 호출하기 위해 표시해두는 의미로 기억해두자.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;트리거 :&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;updateConstraintsIfNeeded&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;이 메소드는 시스템이 정리해서 제약의 변경을 실행할 때 호출된다 직접 호출도 가능하다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;layout&quot;&gt;Layout&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;업데이트 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layoutSubviews&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;하위 뷰들을 배치한다. 현재 뷰와 모든 자식 뷰의 크기와 위치를 제공한다. 이 메소드는 frame을 다시 계산해야할 때 호출하기 때문에 오버라이딩을 해서 조절할 수 있지만 직접 호출하는 것은 금지되어있다. 대신 시스템에 요청하기 위해 여러 방식들이 존재한다. 우리는 레이아웃의 크기나 위치와 연관된 로직을 layoutSubviews가 완료될 때 viewDidLayoutSubviews에 호출해야한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;플래그 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setNeedsLayout&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;시스템에 요청하는 여러 방식 중 하나이다. layoutSubViews를 가장 적은 부하로 호출할 수 있다 강제로 레이아웃을 갱신하고 싶다면 다음 RunLoop에 갱신이 된다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;트리거 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layoutIfNeeded&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;setNeedsLayout과 달리 &lt;strong&gt;즉시&lt;/strong&gt; layoutSubviews를 호출할 수 있다 하지만 호출했을 때 View가 재조정되어야하는 이유가 없다면 layoutSubviews는 호출되지다 않는 만약 우리가 동일한 RunLoop에서 레이아웃의 업데이트 없이 layoutIfNeeded를 두 번 호출했다면, 두 번째 호출은 layoutSubviews를 발생시키지 않는다. 애니메이션하는 상황에서 특히 유용하다&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;draw&quot;&gt;Draw&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;UIView의 인스턴스 메소드로 UIView 객체 인스턴스로부터 접근해서 사용하는 메소드이다 rect라는 파라미터를 받아 업데이트 해야하는 영역을 갖는다 Core Graphics, UIkit 등에서 뷰의 컨텐츠를 그리는 기술을 사용하는 하위뷰들은 해당 메소드를 오버라이드해야하며 해당 구현부에 그리기 코드를 작성해야한다&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;대략 대충 구현을 하자면…&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TestView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIView&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;numberOfPoints&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;didSet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;setNeedsDisplay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//numberOfPoints가 변하면 뷰를 그리는게 달라지기 때문에 추가함&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CGRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numberOfPoints&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      	&lt;span class=&quot;nf&quot;&gt;drawLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      	&lt;span class=&quot;nf&quot;&gt;drawTriangle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      	&lt;span class=&quot;nf&quot;&gt;drawPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;직접호출해선 안된다 뷰의 일부분이 다시 그려져야한다면 &lt;code&gt;setNeedsDisplay&lt;/code&gt; 로 시스템에 알려줄 수 있다&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;출처&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://daeun28.github.io/이론/post22/#제약-조건constraints&lt;/li&gt;
  &lt;li&gt;https://jinshine.github.io/2018/06/07/iOS/오토레이아웃(AutoLayout)과%20Layout%20개념/&lt;/li&gt;
  &lt;li&gt;http://monibu1548.github.io/2019/02/08/layout-cycle/&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Gayo</name></author><category term="View" /><category term="iOS에서 레이아웃을 접근하는 방법 3가지" /><category term="View Layout Cycle" /><summary type="html">iOS에서 레이아웃을 접근하는 방법 3가지</summary></entry><entry><title type="html">RxSwift + UITableView 무한스크롤 구현하기</title><link href="https://ga-yo.github.io/rxswift/RxSwift%EB%A1%9C-%EB%AC%B4%ED%95%9C%EC%8A%A4%ED%81%AC%EB%A1%A4/" rel="alternate" type="text/html" title="RxSwift + UITableView 무한스크롤 구현하기" /><published>2021-05-30T19:31:28+00:00</published><updated>2021-05-30T19:31:28+00:00</updated><id>https://ga-yo.github.io/rxswift/RxSwift%EB%A1%9C%20%EB%AC%B4%ED%95%9C%EC%8A%A4%ED%81%AC%EB%A1%A4</id><content type="html" xml:base="https://ga-yo.github.io/rxswift/RxSwift%EB%A1%9C-%EB%AC%B4%ED%95%9C%EC%8A%A4%ED%81%AC%EB%A1%A4/">&lt;p&gt;여러 프로젝트를 진행하다보면 UITableView를 이용해 무한스크롤을 구현해야하는 경우가 많습니다.&lt;/p&gt;

&lt;p&gt;저도 학교에서 프로젝트들을 진행하였는데 무한스크롤을 사용안하는 프로젝트를 찾기 어려울만큼 가장 보편적으로 사용되는 기능입니다. 이 기능을 구현하기 위해서 우리가 알아야할 것은 UITableView가 언제 스크롤이 바닥에 도달하는지가 쟁점입니다.&lt;/p&gt;

&lt;p&gt;복잡할 것 같지만 의외로 간단하게 해결할 수 있습니다. RxSwift를 이용해 무한스크롤을 구현해봅시다&lt;/p&gt;

&lt;h3 id=&quot;uiscrollviewrx&quot;&gt;☝🏻UIScrollView+Rx&lt;/h3&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIScrollView&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;reachedBottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contentOffset&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatMap&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contentOffset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scrollView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                
                &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;visibleHeight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contentInset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contentInset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contentOffset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contentInset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;top&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;threshold&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contentSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visibleHeight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;threshold&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;just&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;먼저 UITableView에 UIScrollView가 내장되어있고 무한스크롤은 현재 스크롤 된 값을 알아야하기 때문에 UIScrollView를 Extension 해주었습니다. 그리고 &lt;code&gt;reachedBottom&lt;/code&gt; 변수로 만약 스크롤 지점이 바닥이라면 Void로 이벤트를 넘겨주고 아니라면 empty()를 주었습니다.&lt;/p&gt;

&lt;h3 id=&quot;uitableview-event-전달&quot;&gt;✌🏻UITableView Event 전달&lt;/h3&gt;

&lt;p&gt;프로젝트는 RxSwift+MVVM으로 구성되어있기 때문에 아래의 코드는 VC에서 VM으로 바인딩을 해주는 코드입니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;MainViewModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;getPosts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asSignal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;onErrorJustReturn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt;
                                        &lt;span class=&quot;nv&quot;&gt;loadDetail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mainTableView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;itemSelected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asSignal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                                        &lt;span class=&quot;nv&quot;&gt;postScrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selectScrap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asSignal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                                        &lt;span class=&quot;nv&quot;&gt;getMorePosts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mainTableView&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reachedBottom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asSignal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;onErrorJustReturn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt;
                                        &lt;span class=&quot;nv&quot;&gt;getOtherProfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selectProfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asSignal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;viewModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;getMorePosts를 보면&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mainTableView.reachedBottom.asSignal(onErrorJustReturn: ())&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;여기서 UITableView가 스크롤의 바닥에 위치한다면 이벤트를 전달한다고 보여지고 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;in-viewmodel&quot;&gt;👌🏻In ViewModel&lt;/h3&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getMorePosts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asObservable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pagination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatMap&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getPosts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pagination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;getPostsData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;서버 오류&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;disposed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;by&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disposeBag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;여기서 getMorePosts의 이벤트를 전달받았다면 불러올 현재 페이지를 +1 시키고 api를 요청합니다. 그렇게 받아온 값들을 getPostsData에 넣어주고 Output으로 보내주면은 pagination이 끝이 납니다..!&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;출처&quot;&gt;출처&lt;/h3&gt;

&lt;p&gt;https://github.com/RGSSoftware/UIScrollViewReachedBottom&lt;/p&gt;</content><author><name>Gayo</name></author><category term="RxSwift" /><category term="UIScrollView + Rx" /><category term="UITableView Event 전달" /><category term="In ViewModel" /><summary type="html">여러 프로젝트를 진행하다보면 UITableView를 이용해 무한스크롤을 구현해야하는 경우가 많습니다.</summary></entry><entry><title type="html">RxSwift-Scheduler 알아보기</title><link href="https://ga-yo.github.io/rxswift/RxSwift-with-Scheduler/" rel="alternate" type="text/html" title="RxSwift-Scheduler 알아보기" /><published>2021-02-28T01:31:50+00:00</published><updated>2021-02-28T01:31:50+00:00</updated><id>https://ga-yo.github.io/rxswift/RxSwift-with-Scheduler</id><content type="html" xml:base="https://ga-yo.github.io/rxswift/RxSwift-with-Scheduler/">&lt;h3 id=&quot;scheduler&quot;&gt;Scheduler?&lt;/h3&gt;

&lt;p&gt;스케줄러는 스레드의 Reactive적 개념입니다. 요구사항에 맞게 비동기로 동작할 수 있도록 바꿔줘야하는데 이때 스케줄러를 사용합니다. 한 마디로 작업이 실행되는 스레드를 정해주는 클래스라고 볼 수 있습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;스케줄러는 Rx 코드를 어느 스레드에서 실행할지 지정할 수 있습니다.&lt;/li&gt;
  &lt;li&gt;Cocoa에선 멀티 스레딩 처리를 위해서 GCD를 사용하지만 RxSwift는 Scheduler로 이용합니다.&lt;/li&gt;
  &lt;li&gt;스케줄러를 별도로 지정하지 않으면 main 스테르에서 동작을 실행합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;mainScheduler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;MainScheduler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;concurrentScheduler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ConcurrentDispatchQueueScheduler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;qos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;scheduler-연산자&quot;&gt;Scheduler 연산자&lt;/h3&gt;

&lt;h4 id=&quot;observeon&quot;&gt;observeOn()&lt;/h4&gt;

&lt;p&gt;작업 수행을 다른 스케줄러에서 하고 싶을 때&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sequence1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backgroundScheduler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;이건 백그라운드 스케줄러에서 실행될 것입니다.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;MainScheduler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
  	&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;이건 메인 스케줄러에서 실행될 것입니다.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;여러 번 호출할 수 있습니다&lt;/li&gt;
  &lt;li&gt;동작하는 스레드를 바꿀 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;subscribeon&quot;&gt;subscribeOn()&lt;/h4&gt;

&lt;p&gt;sequence 생성과 dispose call을 특정 스케줄러에서 하고 싶을 때, Observable의 프로세싱이 어디서 일어나게 할 것인지 결정하는 연산자입니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fruit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;observer&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;observer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[apple]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;observer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[pineapple]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;observer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[strawberry]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Disposables&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;globalScheduler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ConcurrentDispatchQueueScheduler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fruit&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;subscribeOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;globalScheduler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;disposed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;by&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;observeOn() 함수는 처리된 결과를 구독자에게 전달하는 스레드를 지정합니다.&lt;/li&gt;
  &lt;li&gt;처음 지정한 스레드를 고정시키므로 다시 호출해도 무시합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;scheduler의-종류&quot;&gt;Scheduler의 종류&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Serial&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Rx가 직렬적으로 진행됩니다&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Concurrent&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Rx가 동시에 진행됩니다&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;main&quot;&gt;Main&lt;/h4&gt;

&lt;p&gt;메인 스레드에서 가장 위에 존재하는 것으로 UI를 갱신하려면 이 스케줄러로 변경하여 사용됩니다.&lt;/p&gt;

&lt;p&gt;API request같은 heavy task는 피해야합니다.&lt;/p&gt;

&lt;h4 id=&quot;current&quot;&gt;Current&lt;/h4&gt;

&lt;p&gt;현재 스레드를 이용합니다.&lt;/p&gt;

&lt;h4 id=&quot;serialdispatchqueue&quot;&gt;SerialDispatchQueue&lt;/h4&gt;

&lt;p&gt;background에서 추출하는 일을 처리할 때 사용됩니다&lt;/p&gt;

&lt;p&gt;Ex) firebase를 사용할 때 서버의 endpoint에 너무 많은 pressured를 줄일 수 있습니다.&lt;/p&gt;

&lt;h4 id=&quot;concurrentqueue&quot;&gt;ConcurrentQueue&lt;/h4&gt;

&lt;p&gt;SerialDispatchQueue와 같이 추출하는 일을 수행할 때 처리됩니다. 하지만 병렬적!!&lt;/p&gt;

&lt;h4 id=&quot;test&quot;&gt;Test&lt;/h4&gt;

&lt;p&gt;말그대로 테스트를 위한 것이며 production code에는 사용하지 않습니다.&lt;/p&gt;</content><author><name>Gayo</name></author><category term="RxSwift" /><category term="Scheduler" /><category term="RxSwift" /><summary type="html">Scheduler?</summary></entry><entry><title type="html">RxSwift-Subject 알아보기</title><link href="https://ga-yo.github.io/rxswift/RxSwift-Subject/" rel="alternate" type="text/html" title="RxSwift-Subject 알아보기" /><published>2021-02-22T18:31:50+00:00</published><updated>2021-02-22T18:31:50+00:00</updated><id>https://ga-yo.github.io/rxswift/RxSwift-Subject</id><content type="html" xml:base="https://ga-yo.github.io/rxswift/RxSwift-Subject/">&lt;h3 id=&quot;subject&quot;&gt;Subject!&lt;/h3&gt;

&lt;p&gt;Observable과 Observer 역할을 둘 다 수행할 수 있는 특별한 형태입니다. Observer인 동시에 Observable이죠. 실시간으로 Observable에 새로운 값을 추가하고 subscribers에게 방출합니다. 그리고 Subjects는 Cold Observable을 Hot하게 변형하는 효과를 얻을 수 있습니다. Multicast 방식으로 구독하고 있는 Observer들에게 값을 발행할 수 있습니다.&lt;/p&gt;

&lt;p&gt;Observable을 상속하고 있으며 ObserverType 프로토콜을 채택하고 있습니다. 이는 Subject가 &lt;strong&gt;Observable + Observer&lt;/strong&gt; 라는 것을 의미합니다.&lt;/p&gt;

&lt;p&gt;여기서 질문이 생깁니다. 그러면 Observable과 Subject의 차이점은 뭘까요?&lt;/p&gt;

&lt;h4 id=&quot;observable-vs-subject&quot;&gt;Observable vs Subject&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Subject&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Observable&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;multicast방식이기 때문에 여러 개의 Observer에게 이벤트를 발행&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;반대로 unicast 방식이므로 하나의 Observer에게만 이벤트를 발행&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Observer들의 정보를 저장하고 발행된 이벤트를 모든 Observer에게 제공&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Observer가 구독하게 되면 그때마다 새로 create하여 발행하는 과정&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;state를 가지고 data를 메모리에 저장&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;단지 함수일 뿐, state 존재 X&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;자주 데이터를 저장하고 수정할 때&lt;br /&gt;여러 개의 옵저버가 data를 관찰해야할 때&lt;br /&gt; Observer와 Observable 사이의 프록시 역할&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;하나의 Observer에 대한 간단한 Observable이 필요할 때&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;varieties-of-subject&quot;&gt;Varieties of Subject&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;AysncSubject&lt;/p&gt;

    &lt;p&gt;&lt;img width=&quot;520&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/108673391-eb310f00-7526-11eb-80a6-6d36bf7ceff7.png&quot; /&gt;&lt;/p&gt;

    &lt;p&gt;마블 다이어그램을 보게되면 Observable로부터 배출된 마지막 값을 배출하고 소스 Observable의 동작이 완료된 후에야 동작합니다. 첫번째 subscribe 라인에서 맨마지막 값을 배출하게 되면 파란색 이벤트입니다. 그리고 두번째 subscribe 라인에서 맨마지막 값 역시 파란색 이벤트이므로 위의 사진과 같이 배출하게됩니다.&lt;/p&gt;

    &lt;p&gt;❗️만약 해당 Observable이 오류로 인해 종료될 경우엔 아무 항목도 배출하지 않고 발생한 오류를 그대로 전달합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;BehaviorSubject&lt;/p&gt;

    &lt;p&gt;&lt;img width=&quot;521&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/108673421-f84dfe00-7526-11eb-9277-bd8fe97628dc.png&quot; /&gt;&lt;/p&gt;

    &lt;p&gt;BehaviorSubject는 구독하기 시작하면 초기값을 가진 형태의 subject라고 볼 수 있습니다. 가장 최근에 발행한 항목의 발행을 시작하며 그 이후의 이벤트들에 의해 발행된 항목들을 계속 발행합니다.&lt;/p&gt;

    &lt;p&gt;❗️만약 오류 때문에 종료되면 아무런 항목도 배출하지 않고 Observable에서 발생한 오류를 그대로 전달합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;PublishSubject&lt;/p&gt;

    &lt;p&gt;&lt;img width=&quot;521&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/108673439-026ffc80-7527-11eb-8cb6-b5fca1f9e898.png&quot; /&gt;&lt;/p&gt;

    &lt;p&gt;마블 다이어그램에서 보면 구독 이후에 Observable이 배출한 이벤트들만 Observer에게 배출하는 형태를 볼 수 있습니다. PublishSubject 사용 시 주의할 점은 subject가 생성되는 시점과 Observer가 이 subject를 구독하기 시작하는 시점 그 사이에 배출되는 항목들은 잃어버릴 수 있습니다. 그때를 대비해 모든 Observer가 구독을 시작했는지 체크하는 cold observable들을 생성하거나 ReplaySubject를 사용하면 해결할 수 있습니다.&lt;/p&gt;

    &lt;p&gt;❗️만약 오류 때문에 종료되면 아무런 항목도 배출하지 않고 Observable에서 발생한 오류를 그대로 전달합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;ReplaySubject&lt;/p&gt;

    &lt;p&gt;&lt;img width=&quot;521&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/108673455-0d2a9180-7527-11eb-90ad-7fd5a386088b.png&quot; /&gt;&lt;/p&gt;

    &lt;p&gt;Observer가 구독을 시작한 시점과 관계없이 Observable들이 배출한 모든 항목들을 모든 Observer에게 배출합니다. 확실히 여태까지 봐온 다이어그램과의 차이가 있는 걸 느끼죠? 늦게 구독을 시작해도 전에 배출된 이벤트들도 배출됩니다.&lt;/p&gt;

    &lt;p&gt;❗️멀티스레드 환경에서는 Observable 계약 위반과 Subject에서 어느 항목 또는 알림을 먼저 재생해야하는지 모호함이 발생하기 때문에 호출을 유발시키는 onNext 메소드는 사용하지 않도록 주의해햐합니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;example-codes&quot;&gt;Example Codes&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;AysncSubject&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;BehaviorSubject&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;RxSwift&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;disposeBag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DisposeBag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;subject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;BahaviorSubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;init&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Last Issue&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Last Issue&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Issue 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;ul&gt;
      &lt;li&gt;RxJava&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;nc&quot;&gt;BehaviorSubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BehaviorSubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   
 &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   
 &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;one&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;two&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;three&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//default one two three&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;PublishSubject&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;RxSwift&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;disposeBag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DisposeBag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;subject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;PublishSubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Issue 2&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Issue 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;ul&gt;
      &lt;li&gt;RxJava&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;PublishSubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PublishSubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getFirstObserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt; 
   
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//1 2 3&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getSecondObserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   
&lt;span class=&quot;c1&quot;&gt;//4&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onComplete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;ReplaySubject&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;RxSwift&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;disposeBag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DisposeBag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;subject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ReplaySubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;bufferSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subscribe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Issue 4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Issue 2&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Issue 3&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Issue 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;Subscribe 되는 시점에서 2개 (bufferSize 만큼의 최신 이벤트를 저장)&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;RxJava&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;ReplaySubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReplaySubject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getFirstObserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onNext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onComplete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getSecondObserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;</content><author><name>Gayo</name></author><category term="RxSwift" /><category term="Subject" /><category term="RxSwift" /><summary type="html">Subject!</summary></entry><entry><title type="html">ARC上</title><link href="https://ga-yo.github.io/arc/ARC%E4%B8%8B/" rel="alternate" type="text/html" title="ARC上" /><published>2021-02-21T03:13:09+00:00</published><updated>2021-02-21T03:13:09+00:00</updated><id>https://ga-yo.github.io/arc/ARC%E4%B8%8B</id><content type="html" xml:base="https://ga-yo.github.io/arc/ARC%E4%B8%8B/">&lt;p&gt;전까지는 클래스끼리 변수에서의 강한 참조 순환을 봤는데 변수 뿐만아니라 클로저와 관계되어서 발생할 수도 있습니다. 그래서 이번에는 마지막으로 클로저의 강한 참조 순환에 대해서 알아보겠습니다&lt;/p&gt;

&lt;p&gt;클로저는 completion blocks, callbacks 고차함수 등등 많은 고셍서 사용되는 것을 볼 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sayHello&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이렇게 말이죠.&lt;/p&gt;

&lt;p&gt;그리고 이스케이핑 클로저에서는 self를 명시적으로 언급해야하는데 그때 강한 참조 순환이 일어날 수 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;클로저에서의-강한-순환-참조&quot;&gt;클로저에서의 강한 순환 참조&lt;/h3&gt;

&lt;p&gt;그리고 클로저에서는 selff를 캡처하기 때문에 강한 참조 순환이 발생할 수도 있습니다. 그럴경우 클로저 캡쳐 리스트를 사용하여 강한 참조 순환을 해결할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;HTMLElemnet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;asHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//클로저 사용&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//self 캡쳐!&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;text&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deinit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;여기 HTMLElement 클래스가 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;paragraph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;HTMLElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;HTMLElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; hello world&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paragraph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;paragraph&lt;/code&gt;가 옵셔널로 선언되어서 nil을 할당할 수 있지만 인스턴스와 클로저 간에 강한 참조 순환이 일어납니다 그래서 nil을 할당하더라도 해당 인스턴스는 해제되지 않습니다.&lt;/p&gt;

&lt;h3 id=&quot;클로저에서의-강한-순환-참조-해결&quot;&gt;클로저에서의 강한 순환 참조 해결&lt;/h3&gt;

&lt;p&gt;클로저에서 캡쳐 참조에 약한 참조 혹은 미소유 참조를 지정하면 해결할 수 있습니다. 이때 약한 참조와 미소유 참조인가를 정할 땐 코드의 상호관계에 달려있습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;캡쳐리스트 정의&lt;/p&gt;

    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;someClosure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;unowned&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;약한 참조와 미소유 참조&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;약한 참조는 참조가 먼저 해제되는 경우에 사용합니다&lt;/li&gt;
      &lt;li&gt;미소유 참조는 같은 시점이나 나중 시점에 해제되는 경우입니다. 하지만 캡쳐리스트가 절대 nil이 될 수 없다면 그것은 반드시 약한 참조가 아닌 미소유 참조로 캡쳐되어야합니다.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;HTMLElemnet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;asHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;unowned&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /&amp;gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deinit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;paragraph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;HTMLElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;HTMLElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; hello world&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paragraph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;asHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
   
&lt;span class=&quot;n&quot;&gt;paragraph&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//메모리에서 해제됨!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;아까의 코드와 달라진 점은 클로저에 캡쳐리스트로 미소유 참조를 추가하였습니다. 앞서와는 다르게 클로저에서 HTMLElement 인스턴스를 미소유 참조로 참조하고 있습니다. 결국 강한 참조 순환이 되지 않으므로 마지막 줄에서 nil을 할당해주어도 메모리에서 해제될 수 있습니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;</content><author><name>Gayo</name></author><category term="ARC" /><category term="closure" /><summary type="html">전까지는 클래스끼리 변수에서의 강한 참조 순환을 봤는데 변수 뿐만아니라 클로저와 관계되어서 발생할 수도 있습니다. 그래서 이번에는 마지막으로 클로저의 강한 참조 순환에 대해서 알아보겠습니다</summary></entry><entry><title type="html">ARC上</title><link href="https://ga-yo.github.io/arc/ARC%E4%B8%AD/" rel="alternate" type="text/html" title="ARC上" /><published>2021-02-18T20:47:09+00:00</published><updated>2021-02-18T20:47:09+00:00</updated><id>https://ga-yo.github.io/arc/ARC%E4%B8%AD</id><content type="html" xml:base="https://ga-yo.github.io/arc/ARC%E4%B8%AD/">&lt;h3 id=&quot;strong-weak-unowned&quot;&gt;❓strong, weak ,unowned&lt;/h3&gt;

&lt;p&gt;ARC 전편에서는 ARC가 무엇이고 다른 메모리 관리 기법과 비교해보며 이해를 해보았습니다. 이번에는 ARC에서 자주 언급되는 내용인 strong, weak, unowned을 알아보며 메모리 누수를 예방해봅시다&lt;/p&gt;

&lt;h3 id=&quot;강한-순환-참조-&quot;&gt;강한 순환 참조 ??&lt;/h3&gt;

&lt;p&gt;앞선 예제에서 보았다시피 ARC에서 기본적으로 참조 횟수에 대해 추적하고 있기 때문에 더이상 사용하지 인스턴스는 자동으로 메모리에서 해제되게 됩니다. 하지만 절대로 메모리에서 해제되지 않는 경우도 있습니다. 바로 &lt;strong&gt;강한순환참조&lt;/strong&gt; 때문에 말이죠&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
	&lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;apartment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apartment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deinitalized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apartment&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
	&lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tenant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deinitalized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;john&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unit4A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apartment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;John Appleseed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//john은 Person에 대한 강한 참조를 갖음&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apratment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;4A&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//unit4A는 Apartment에 대한 강한 참조를 갖음&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이 코드의 흐름을 보면 &lt;code&gt;var john&lt;/code&gt; 에 대해선 Person 인스턴스로 name과 apartment가 있고 &lt;code&gt;var unit4A&lt;/code&gt; 에 대해선 Apartment 인스턴스로 unit과 tenant가 있습니다. 여기서 강한 참조를 갖는 이유는 기본적으로 weak, unowned로 설정해주지 않는 경우에 strong으로 사용되기 때문입니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apratment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tenant&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;john&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;인스턴스 안의 apartment와 tenant가 각각 Apartment, Person 인스턴스를 참조하고 있는 상황이 됩니다. 이로써 Person 인스턴스의 참조 횟수는 2이고 Apartment 참조 횟수도 2가 된 상황입니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//이렇게 해도 참조카운트가 0이 되지 않아서 deinit은 호출되지 않음&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;인스턴스 해지를 해보면 두 인스턴스는 해지되지 않습니다. 왜냐하면 Person 인스턴스와 Apartment 인스턴스의 변수가 각각 상호 참조를 하고 있어 참조 횟수가 1이기 때문에 이 두 인스턴스는 해지되지않고 &lt;strong&gt;메모리 누수&lt;/strong&gt; 가 발생합니다&lt;/p&gt;

&lt;p&gt;이 상황에서 해결할 수 있는 방법은 &lt;code&gt;weak&lt;/code&gt; 과 &lt;code&gt;unowned&lt;/code&gt; 를 통해 가능합니다.&lt;/p&gt;

&lt;h3 id=&quot;강한-참조-순환-문제-해결&quot;&gt;강한 참조 순환 문제 해결&lt;/h3&gt;

&lt;h4 id=&quot;weak약한-참조&quot;&gt;weak(약한 참조)&lt;/h4&gt;

&lt;p&gt;해당 인스턴스에 참조 횟수를 증가시키지 않으며 참조하고 있는 인스턴스가 먼저 메모리에서 해제될 때 사용합니다.&lt;/p&gt;

&lt;p&gt;약한 참조로 선언하게 되면 참조하고 있는 것이 먼저 메모리에서 해제되기 때문에 ARC는 약한 참조로 선언된 참조 대상이 해지되면 런타임에 자동으로 참조하고 있는 변수에 nil을 할당합니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;apartment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apartment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; is being deinitialized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apartment&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tenant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Apartment &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; is being deinitialized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;john&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unit4A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apartment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;John Appleseed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Apartment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;4A&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apartment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tenant&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;john&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아까 강한 순환 참조를 일으킨 코드와 별 다른 차이점을 느끼지 못할 수도 있습니다. 이 코드에서 가장 중요한 부분은 &lt;code&gt;tenant&lt;/code&gt; 를 어떻게 선언해줬나 입니다. 약한 참조로 선언해줬으니 참조 횟수에도 차이가 생깁니다.  Apartment의 tenant변수가 Person 인스턴스를 약한 참조(weak)로 참조하고 있다는 것입니다. 그래서 이 시점에서  Apartment 인스턴스의 참조횟수는 변함없이 2이고 Person 인스턴스에 대한 참조 회수는 변수 john이 참조하고 있는 1회 뿐입니다.&lt;/p&gt;

&lt;p&gt;weak 인 상태로 선언된 참조 대상이 해지 되면 런타임에 자동으로 참조하고 있는 변수에 nil 할당하게 됩니다. 즉 해당 객체가 nil이여야 합니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;서로 강한 순환 참조가 일어나지 않기 때문에 인스턴스 해지가 되면서 더 이상 Person 인스턴스를 참조하는 것이 없어집니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;unit4A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;john이 해지된 이후에 Apartment 인스턴스를 참조하는 개체도 사라지게 되면서 Apartment 인스턴스도 메모리에서 해지됩니다.&lt;/p&gt;

&lt;h4 id=&quot;unowned미소유-참조&quot;&gt;unowned(미소유 참조)&lt;/h4&gt;

&lt;p&gt;해당 인스턴스에 참조 횟수를 증가 시키지 않으며 weak 과 다르게 절대 nil을 할당하지 않습니다. 그리고 인스턴스가 현재 참조하고 있는 것과 같은 생애주기를 갖거나 더 긴 생애주기를 갖기 때문에 그 값이 있다고 판단합니다. unowned는 non-optional 타입이기 때문에 값이 있다고 확신할 때만 쓰는 것이 좋습니다. 값이 없을 때 접근한다면 런타임 에러라는 결과를 가져올 수 있기 때문입니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Customer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;card&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CreditCard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
	&lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deinitialized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CreditCard&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UInt64&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;unowned&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cusomter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Cusomter&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UInt64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  	&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deinitialized&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;john&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;john&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;card&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CreditCard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1234_5678_9012_3456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;john&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;해당 코드는 Customer, CreditCard 두 개의 클래슥 존재합니다. 여기서 unowned이 사용된 곳을 찾을 수 있나요? 바로 CreditCard에 customer입니다. 이유는 고객과 신용카드를 비교해 봤을때 신용카드는 없더라도 사용자는 남아있을 것이기 때문입니다.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;john&lt;/code&gt; 은 CreditCard 인스턴스, Customer 인스턴스를 하지만 미소유 참조를 하고 있기 때문에 Customer 인스턴스에 대한 참조 횟수는 1이 되게 됩니다.&lt;/p&gt;

&lt;h3 id=&quot;-weak-vs-unowned&quot;&gt;🥊 weak vs unowned&lt;/h3&gt;

&lt;p&gt;약한 참조과 미소유 참조는 nil의 유무에 따라 구분지을 수 있습니다. 하지만 이 경우를 제외한 제 3의 경우도 생길 수 있습니다. 이 경우에 바로 &lt;strong&gt;미소유&lt;/strong&gt; 프로퍼티를 &lt;strong&gt;암시적 옵셔널 프로퍼티 언래핑&lt;/strong&gt;을 사용해 참조 문제를 해결합니다&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Country&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;capitalCity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//여기!&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;capitalName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalCity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;capitalName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;City&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;unowned&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Country&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Stirng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;country&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;country&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;City에 대한 생성자는 Country 생성자 내에서 호출하게 됩니다. Country의 capitalCity는 초기화 단계에서 City 클래스에 초기화 된 후 사용되게 됩니다. 즉 실제로 Country의 capitalCity는 옵셔널이 되어야합니다. &lt;strong&gt;하지만 여기서는 느낌표 연산자(!)를 이용해 명시적으로 강제 언래핑을 시켰습니다&lt;/strong&gt;. 이 프로퍼티는 nil 값을 기본적으로 가지고 있지만 옵셔널을 벗길 필요없이 접근될 수 있음을 의미합니다. 그렇게 암시적 언래핑이 돼서 Country에서 name을 초기화하는 시점에 self를 사용할 수 있게됩니다.&lt;/p&gt;

&lt;p&gt;= City에서는 강한 참조 순환을 피하기 위해 미소유 참조로 country를 선언해서 두 인스턴스를 문제없이 사용할 수 있습니다.&lt;/p&gt;</content><author><name>Gayo</name></author><category term="ARC" /><category term="strong" /><category term="weak" /><category term="unowned" /><summary type="html">❓strong, weak ,unowned</summary></entry><entry><title type="html">ARC上</title><link href="https://ga-yo.github.io/arc/ARC%E4%B8%8A/" rel="alternate" type="text/html" title="ARC上" /><published>2021-02-18T18:35:28+00:00</published><updated>2021-02-18T18:35:28+00:00</updated><id>https://ga-yo.github.io/arc/ARC%E4%B8%8A</id><content type="html" xml:base="https://ga-yo.github.io/arc/ARC%E4%B8%8A/">&lt;h3 id=&quot;arcautomatic-reference-counting&quot;&gt;ARC(Automatic Reference Counting)&lt;/h3&gt;

&lt;p&gt;오늘은 Swift에서 앱의 메모리 사용을 관리하는 ARC에 대해서 알아보도록 하겠습니다! ARC는 iOS 개발하는 사람이라면 필수적으로 알아야하는 것 중 하나입니다. 어떤 언어를 사용하든 메모리 관리는 중요하기 때문이죠! 자바에서 GC를 사용하는 것처럼 Swift에선 메모리 관리로 ARC를 사용합니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;arc가-뭐야&quot;&gt;ARC가 뭐야?&lt;/h3&gt;

&lt;p&gt;Objective-C 로 개발하던 시기에는 개발자가 직접 메모리 관리를 하였으나 ARC를 사용하면서 자동으로 참조 횟수를 관리가 가능해졌다. 메모리를 할당하면 참조 횟수가 자동으로 올라가고 더이상 사용되지 않는 인스턴스를 메모리에서 해지합니다. 참고로 참조 횟수는 클래스 타입의 인스턴스에만 적용되고 값 타입인 구조체 열거형 등에는 적용되지 않습니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;동작-방법&quot;&gt;동작 방법&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;클래스의 새 인스턴스를 &lt;strong&gt;만들 때마다&lt;/strong&gt; ARC는 인스턴스 정보를 담는데 필요한 적절한 크기의 메모리를 할당합니다. 이때 그 메모리는 인스턴스에 대한 정보와 관련된 저장 프로퍼티 값도 가지게 됩니다.&lt;/li&gt;
  &lt;li&gt;인스턴스가 더이상 사용되지 않는다면 ARC는 그 인스턴스가 차지하고 있는 메모리를 해지시키고 그 공간을 다른 용도로 사용할 수 있게 확보해둡니다.&lt;/li&gt;
  &lt;li&gt;ARC는 최소 하나라고 그 인스턴스에 대한 참조가 있는 경우 그 인스턴스를 메모리에서 해지하지 않습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❗️ 만약 아직 사용 중인 인스턴스를 메모리에서 해지했을 때 인스턴스의 프로퍼티에 접근한다면 앱은 아마 크래시가 발생하게됩니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;사용-방법&quot;&gt;사용 방법&lt;/h3&gt;

&lt;p&gt;ARC의 동작을 이해하기 위해 간단하게 사용해보도록 하겠습니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Flower&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
  
  &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;init&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;deinit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deinit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;reference1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Flower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;reference2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Flower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;reference3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Flower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;Flower&lt;/code&gt; 라는 클래스를 선언해주었고 그 아래 reference 변수 3개를 선언하였습니다. 클래스 인스턴스 생성에 참조를 하게 해주면&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;reference1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Flower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rose&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//print &quot;init&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Print 문으로 인스턴스 생성이 되었다는 것을 알 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;reference2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reference1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;reference3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reference1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;reference 2, 3은 모두 처음에 reference1이 참조하는 &lt;code&gt;Flower&lt;/code&gt; 인스턴스를 참조하게 됩니다. 이때 &lt;code&gt;Flower&lt;/code&gt; 인스턴스에 대한 &lt;strong&gt;참조 횟수는 3&lt;/strong&gt;이 됩니다&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;reference1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;reference2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;nil로 reference1, 2의 참조를 해지하게 됩니다. 이 시점에서 참조횟수는 얼마일까요? 아직 reference3의 참조가 남아있으니 1이 남습니다. 아까 최소 하나라도 인스턴스에 대한 참조가 있다면 메모리에서 해지할 수 없다고 했던 것처럼 지금 상태로는 &lt;code&gt;Flower&lt;/code&gt; 인스턴스의 해지가 되지 않습니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;reference3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이 코드를 마지막으로 더이상 &lt;code&gt;Flower&lt;/code&gt; 인스턴스를 참조하는 것이 없기 때문에 메모리에서 해지됩니다&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-arc-vs-gc&quot;&gt;🥊 ARC vs GC&lt;/h3&gt;

&lt;h4 id=&quot;gc&quot;&gt;GC&lt;/h4&gt;

&lt;p&gt;먼저 GC는 런타임 시 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된 영역을 해제합니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Q. 그렇다면 필요없게 된 영역을 어떻게 해제할까요?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;A. Heap 내에서 객체의 수명을 관리하기 위해(오래된 객체를 판별하기 위해) young, old 구역으로 나뉘고 young은 그 안에서 Eden, Survivor로 나뉘게 됩니다&lt;/p&gt;

  &lt;p&gt;​	&lt;strong&gt;young 영역&lt;/strong&gt;은 새롭게 생성한 객체의 대부분이 여기 위치하고 대부분의 객체가 금방 접근 불가능 상태가 되기 떄문에 많은 객체가 young 영역에서 생성되었다가 사라집니다&lt;/p&gt;

  &lt;p&gt;​	&lt;strong&gt;old 영역&lt;/strong&gt;은 접근 불가능한 상태로 되지 않아 yound 영역에서 살아남은 객체가 여기로 복사됩니다&lt;/p&gt;

  &lt;p&gt;​	여기서 GC는 세 단계로 나뉘게 됩니다.&lt;/p&gt;

  &lt;p&gt;​	- Minor GC  = young 영역만 뒤져서 판별&lt;/p&gt;

  &lt;p&gt;​	- Major GC = old 영역까지 뒤져서 판별&lt;/p&gt;

  &lt;p&gt;​	- Full GC = permanent 영역까지 뒤져서 판별&lt;/p&gt;

  &lt;p&gt;​	영역과 영역 사이를 오가고 여러 GC가 발생할 때마다 더이상 참조되지 않는 객체는 메모리에서 제거되게 됩니다&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;arc와-gc의-차이&quot;&gt;ARC와 GC의 차이&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;가장 큰 차이는 처리되는 시점이다 ARC, GC는 각각 컴파일 시, 런티임 중에 실행되는데 GC와 같이 런타임 중에 메모리를 검사하면 앱 퍼포먼스에 악영향을 줍니다&lt;/li&gt;
  &lt;li&gt;GC는 런타임 외의 메모리 감시를 위한 추가자원이 필요해 한정적인 자원 환경에서 성능 저하가 발생할 수 있으나 ARC는 인스턴스 해제 시점을 컴파일 당시 예측 가능하여 시스템 자원을 추가할 필요가 없습니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;arc-vs-mrc&quot;&gt;🎯ARC vs MRC&lt;/h3&gt;

&lt;h4 id=&quot;mrc&quot;&gt;MRC&lt;/h4&gt;

&lt;p&gt;Menual reference counting 의 약어로 obj-c를 사용할 때 참조를 수동으로 계산해야합니다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;alloc, new, cioy, mutalbeCopy, preserve 등&lt;/strong&gt; 을 사용하여 obj-c에 대한 참조 를 &lt;strong&gt;수동&lt;/strong&gt;으로 만들고 계산 해야합니다. 현재 ARC를 지원함으로써 MRC를 통해 수동으로 메모리 관리는 필요하지 않습니다.&lt;/p&gt;

&lt;p&gt;MRC의 경우 개발자가 직접 카운팅을 해야하기 때문에 인스턴스의 RC에 접근할 수 있는 프로퍼티가 존재합니다. = &lt;code&gt;retainCount&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;하지만 애플 공식 문서에서&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;retainCount의 경우… autorelease pool에 의해 release가 지연된 Count를 갖고있을 수 있어서 &lt;strong&gt;유용한 정보를 얻을 수 있는 방법이 매우 낮다&lt;/strong&gt; 고함&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;arc와-mrc의-차이&quot;&gt;ARC와 MRC의 차이&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;가장 큰 차이는 카운팅을 수동으로 하느냐 자동으로 하느냐입니다.&lt;/li&gt;
&lt;/ol&gt;</content><author><name>Gayo</name></author><category term="ARC" /><category term="ARC" /><summary type="html">ARC(Automatic Reference Counting)</summary></entry><entry><title type="html">URLSession 톺아보고 통신해보기!</title><link href="https://ga-yo.github.io/urlsession/URLSession-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0/" rel="alternate" type="text/html" title="URLSession 톺아보고 통신해보기!" /><published>2021-01-29T01:14:28+00:00</published><updated>2021-01-29T01:14:28+00:00</updated><id>https://ga-yo.github.io/urlsession/URLSession%20%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0</id><content type="html" xml:base="https://ga-yo.github.io/urlsession/URLSession-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0/">&lt;p&gt;Alamofire는 모두가 유용하게 사용하고 있는 네트워킹 라이브러리입니다. 근데 이 라이브러리를 뜯어보면 URLSession으로 시작된 것을 아시나요? 아주 신기합니당 그래서 오늘은 URLSession에 대해서 알아보고 Request랑 Response받는것도 알아보려고 합니다!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/49550838/106137152-ac20cf80-61ad-11eb-955f-c03e995ff695.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;전체적으로 살펴볼 내용은 이 사진에서 보여지는 URLSession과 URLSessionTask입니다.&lt;/p&gt;

&lt;h3 id=&quot;urlsession이란&quot;&gt;URLSession이란?&lt;/h3&gt;

&lt;p&gt;HTTP/HTTPS를 통해 콘텐츠를 주고받는 API를 제공하는 클래스입니다. 앱은 이 API를 사용하여 앱이 실행되고 있지 않거나 iOS에서 앱이 일시 중지된 동안 백그라운드 다운로드를 수행할 수 있습니다. 관련 및 인증을 지원하고 리디렉션 및 작업완료와 같은 이벤트를 수신할 수 있습니다.&lt;/p&gt;

&lt;h4 id=&quot;urlsession-유형urlsessionconfiguration을-통해&quot;&gt;URLSession 유형(URLSessionConfiguration을 통해)&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;기본 세션 - Default Session&lt;/p&gt;

    &lt;p&gt;공유 세션과 매우 유사하게 작동하지만 데이터를 점진적으로 가져오기위해 기본 세션에 delegate를 지정할 수도 있습니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;임시 세션 - Ephemeral Session&lt;/p&gt;

    &lt;p&gt;공유 세션과 유사하지만 캐시, 쿠키 또는 자격 증명을 디스크에 쓰지 않습니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;백그라운드 세션 - Background Session&lt;/p&gt;

    &lt;p&gt;앱이 실행되지 않는 동안 백드라운드에서 콘텐츠 업로드 및 다운로드를 수행할 수 있습니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;urlsession-작업-유형&quot;&gt;URLSession 작업 유형&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;데이터 작업&lt;/p&gt;

    &lt;p&gt;NSData 개체를 사용하여 데이터를 보내고 받습니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;업로드 작업&lt;/p&gt;

    &lt;p&gt;데이터를 전송하고 앱이 실행되지 않는 동안 백그라운드 업로드를 지원합니다&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;다운로드 작업&lt;/p&gt;

    &lt;p&gt;파일 형식으로 데이터를 검색하고 앱이 실행되지 않는동안 백그라운드 다운로드 및 업로드를 지원합니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;urlsessiontask란&quot;&gt;URLSessionTask란?&lt;/h3&gt;

&lt;p&gt;URLSession에서 수행되는 특정 리소스 다운로드와 같은 작업으로 세션은 데이터를 가져오거나 파일을 업로드, 다운로드하는 실제 작업을 수행하는 하나 이상의 Task를 생성합니다.&lt;/p&gt;

&lt;h4 id=&quot;urlsessiontask-유형&quot;&gt;URLSessionTask 유형&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;URLSessionDataTask&lt;/p&gt;

    &lt;p&gt;서버에서 메모리로 데이터를 검색하는 HTTP GET 요청에 사용&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;URLSessionUploadTask&lt;/p&gt;

    &lt;p&gt;전형적으로 HTTP POST, PUT 메소드를 통해서 디시크에서 웹서버로 파일을 전송할 때 사용&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;URLSessionDownloadTask&lt;/p&gt;

    &lt;p&gt;임시의 파일 위치로 원격 서버에서 파일을 다운로드할 때 사용&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apple 공식문서를 보고 내용들을 정리해보았는데 이제는 URLSession을 이용하여 Request, Response를 구현해보도록 하겠습니다.&lt;/p&gt;

&lt;h3 id=&quot;urlsession으로-통신해보기&quot;&gt;URLSession으로 통신해보기&lt;/h3&gt;

&lt;p&gt;URLSession은 Request 할 때 URL 객체를 통해 직접 통신하는 형태와 URLRequest 객체를 만들어서 옵션을 설정하는 형태가 있습니다.&lt;/p&gt;

&lt;p&gt;다음으로 Response는 설정된 Task의 Completion Handler 형태로 response를 받는 형태, URLSessionDelegate를 통해 지정된 메소드를 호출하는 형태가 있습니다.&lt;/p&gt;

&lt;p&gt;이번엔 URLRequest 객체를 만들어서 옵션을 설정하는 형태와 Completion Handler 형태로 request와 response를 받아보겠습니다.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLSession&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLSessionDataTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;components&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLComponents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://urlsession.example.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//var query = URLQueryITem(name: &quot;&quot;, value: &quot;&quot;) 만약 쿼리가 필요하다면&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;components&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dataTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dic&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;JSONSerialization&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;jsonObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                             
     &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;//원하는 작업으로 data 뽑기                               &lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;resume&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;Session 생성, task 생성. 그리고  환경설정을 해줍니다&lt;/li&gt;
  &lt;li&gt;URLComponents로 URL을 구성합니다. 쿼리가 있다면 쿼리를 설정해줍니다. URLComponent에 관련한 설명은 &lt;a href=&quot;https://zeddios.tistory.com/1103&quot;&gt;여기&lt;/a&gt;가 더 좋을 것 같아 첨부합니다.&lt;/li&gt;
  &lt;li&gt;이번엔 URLRequest 객체를 만들어서 옵션을 설정한다고 했으니 URLRequest 기반으로 객체를 만들어줍니다.&lt;/li&gt;
  &lt;li&gt;dataTask(with: ) 를 통해 데이터를 주고 받습니다. JSONSerialization은 json 데이터를 String 형태로 변환하여 Swift에서 사용할 수 있도록 하는 것으로 data를 변환해줍니다.&lt;/li&gt;
  &lt;li&gt;변환한 데이터에 대한 작업을 해서 핸들러를 마무리하고 resume()으로 만들어 dataTask가 시작할 수 있도록 합니다. 모든 작업은 기본적으로 일시정지 상태로 시작하기 때문입니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;출처&quot;&gt;출처&lt;/h4&gt;

&lt;p&gt;https://devmjun.github.io/archive/URLsession&lt;/p&gt;

&lt;p&gt;https://hcn1519.github.io/articles/2017-07/iOS_URLSession&lt;/p&gt;</content><author><name>Gayo</name></author><category term="URLSession" /><category term="-URLSession이란?" /><category term="-URLSessionTask란?" /><category term="-URLSession으로" /><category term="통신해보기" /><summary type="html">Alamofire는 모두가 유용하게 사용하고 있는 네트워킹 라이브러리입니다. 근데 이 라이브러리를 뜯어보면 URLSession으로 시작된 것을 아시나요? 아주 신기합니당 그래서 오늘은 URLSession에 대해서 알아보고 Request랑 Response받는것도 알아보려고 합니다!</summary></entry><entry><title type="html">ReacotrKit 예제 따라하면서 뿌시기!</title><link href="https://ga-yo.github.io/reactorkit/ReactorKit/" rel="alternate" type="text/html" title="ReacotrKit 예제 따라하면서 뿌시기!" /><published>2021-01-26T23:26:28+00:00</published><updated>2021-01-26T23:26:28+00:00</updated><id>https://ga-yo.github.io/reactorkit/ReactorKit</id><content type="html" xml:base="https://ga-yo.github.io/reactorkit/ReactorKit/">&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/49550838/105825875-6c1de900-6003-11eb-9826-158cbfd7b82c.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;reactorkit이란&quot;&gt;ReactorKit이란?&lt;/h3&gt;

&lt;p&gt;반응형 단방향 앱을 위한 프레임워크로 StyleShare, Kakao를 비롯한 여러기업에서 사용하고 있는 기술입니다. Flux와 Reactive programming의 개념을 결합하여 만들어진 ReactorKit은 사용자 인터랙션과 뷰 상태가 관찰 가능한 스트림을 통해 단방향으로 전달됩니다. 뷰와 비즈니스 로직을 분리할 수 있게 되면서 모듈간 결합도가 낮아지고 테스트하기 쉬워졌다고 합니다.&lt;/p&gt;

&lt;h3 id=&quot;reactorkit의-데이터-흐름&quot;&gt;ReactorKit의 데이터 흐름&lt;/h3&gt;

&lt;p&gt;전체적인 흐름은 View와 Reactor라는 개념을 통해 존재합니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;View는 Action을 Reactor에게 전달합니다.(View는 비즈니스 로직을 수행하지 않음!)&lt;/li&gt;
  &lt;li&gt;Reactor는 전달받은 Action에 따라 비즈니스 로직을 수행합니다.&lt;/li&gt;
  &lt;li&gt;그 후 Reactor는 상태(State)를 변경하여 View에게 전달합니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;여기서 View는 View Controller나 Cell 등을 말합니다&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ReactorKit의 데이터 흐름을 구체화 시킨다면 다음의 사진입니다. Action이 들어오면 두 단계를 거쳐서 State를 변경합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/49550838/105826014-9e2f4b00-6003-11eb-98be-50703b9fbdeb.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Mutate()&lt;/strong&gt; 는 Action 스트림 —&amp;gt; Mutation 스트림으로 변환하는 역할&lt;/p&gt;

    &lt;p&gt;보통 네트워킹이나 비동기 로직 등의 사이드 이펙트를 처리합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Reduce()&lt;/strong&gt; 는 Mutation에서 방출된 값을 받아서 상태를 반환합니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;view&quot;&gt;View&lt;/h3&gt;

&lt;p&gt;! View 프로토콜을 적용하면 View를 정의할 수 있습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;DisposeBag&lt;/strong&gt;속성과&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;bind(reactor: )&lt;/strong&gt; 메서드&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;필수로 필요합니다.&lt;/p&gt;

&lt;h3 id=&quot;reactor&quot;&gt;Reactor&lt;/h3&gt;

&lt;p&gt;! Reactor 프로토콜을 사용하여 정의할 수 있습니다&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;사용자 인터랙션을 표현하는 &lt;strong&gt;Action&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;뷰의 상태를 표현하는 &lt;strong&gt;State&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;상태를 변경하는 가장 작은 단위인 &lt;strong&gt;Mutation&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;가장 첫 상태를 나타내느 &lt;strong&gt;initialState&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;필수로 필요합니다.&lt;/p&gt;

&lt;h3 id=&quot;reactorkit을-써야하는-이유&quot;&gt;ReactorKit을 써야하는 이유?&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;MVVM 구조는 개발자마다 바인딩 방법이 다른데 프레임워크로 강제되는 사용법으로 명확성을 찾을 수 있습니다.&lt;/li&gt;
  &lt;li&gt;가독성이 좋아 협업에도 적합합니다.&lt;/li&gt;
  &lt;li&gt;기존 앱이 이미 존재하는 경우에도 작은 단위부터 ReactorKit을 도입하여 리팩토링이 수월합니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;예제로-보는-실전-연습&quot;&gt;예제로 보는 실전 연습!&lt;/h3&gt;

&lt;p&gt;https://github.com/ReactorKit/ReactorKit 에 기재된 Examples를 보며 ReacotrKit을 익혀보겠습니다.&lt;/p&gt;

&lt;p&gt;GitHubSearch라는 예제입니다.&lt;/p&gt;

&lt;h4 id=&quot;1-reactor-만들기&quot;&gt;1. Reactor 만들기&lt;/h4&gt;

&lt;p&gt;&lt;img width=&quot;638&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/105826037-a7201c80-6003-11eb-9c43-341b88230efb.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;아까 설명했듯이 Reactor 프로토콜을 사용하여 만들어주었습니다. GitHub를 검색하기 위한 구조로 안에 값을 채워주겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;576&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/105826086-b1dab180-6003-11eb-8658-f7e09137feaa.png&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Action&lt;/p&gt;

    &lt;p&gt;updateQuery는 검색한 String을 지칭합니다&lt;/p&gt;

    &lt;p&gt;loadNextPage는 무한스크롤을 위해 만들어졌습니다&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Mutation&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;setQuery는 비즈니스 로직으로 들어갈 쿼리값을 의미합니다&lt;/p&gt;

    &lt;p&gt;setRepos는 검색한 결과인 GItHub의 Repository 데이터를 담습니다&lt;/p&gt;

    &lt;p&gt;appendRepos는 무한 스크롤로 받은 새로운 데이터들을 append해줍니다&lt;/p&gt;

    &lt;p&gt;setLoadingNextPage Next Page를 로딩할 수 있는지 여부 확인&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;query는 현재 검색한 String&lt;/p&gt;

    &lt;p&gt;repos는 검색 결과 데이터&lt;/p&gt;

    &lt;p&gt;nextPage는 페이지 수&lt;/p&gt;

    &lt;p&gt;isLoadingNextPage는 로딩 확인&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;그 다음엔 Action 스트림을 Mutation 스트림으로 바꾸기 위해 mutate()로 구현해보겠습니다&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;743&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/105826190-ce76e980-6003-11eb-825e-4ca3e86193b4.png&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;updateQery를 이용해서 현재 SearchBar에 어떤 String이 찍히고 있으며 그 String에 대한 검색 API를 이용합니다. 그리고 Repository 데이터를 담는 setRepos에 검색 결과를 담아 Mutation에 담습니다.&lt;/li&gt;
  &lt;li&gt;loadNextPage는 무한 스크롤을 사용하기 위해 다음 페이지를 로딩합니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;그리고 reduce()를 구현해봅시다.&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;548&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/105826272-e77f9a80-6003-11eb-85ec-ffe1589c5600.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Mutation에서 전달된 상태를 받아서 방출하는 것이 reduce()의 역할이다. 각 Mutation의 구조들을 State로 방출해주고 있는 모습을 볼 수 있다.&lt;/p&gt;

&lt;p&gt;이 글은 ReactorKit을 중점적으로 다루고 있기 때문에 다른 비즈니스 로직은 생략하도록 하겠습니다.&lt;/p&gt;

&lt;h4 id=&quot;2-reactor의-view-만들기&quot;&gt;2. Reactor의 View 만들기&lt;/h4&gt;

&lt;p&gt;앞서 View를 만들 때 View라는 프로토콜을 명시해야한다고 설명했었습니다. 만약에 Storyboard를 사용하여 UI를 구성할 경우엔 View 프로토콜이 아닌 &lt;strong&gt;StoryboardView 프로토콜&lt;/strong&gt;을 사용하여 바인딩해줘야합니다.&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;643&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/105826300-f1090280-6003-11eb-8502-57428e956d52.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;필수로 DisposeBag과 bind()를 구현한 모습을 볼 수 있습니다. reactor의 타입은 아까 만들어준 Reactor의 이름을 붙이면 됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img width=&quot;573&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/105826398-0aaa4a00-6004-11eb-958e-8bc8a7f3655e.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Action부터 바인딩 해봅시다.&lt;/p&gt;

&lt;p&gt;설정한 Action은 updateQuery와 loadNextPage입니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;searchBar의 text를 reactor의 action에 바인딩&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;tableViewdml height를 계산해서 reactor의 action에 바인딩&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img width=&quot;617&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/49550838/105826452-17c73900-6004-11eb-9768-769b207d726a.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그 다음으론 State를 바인딩 해주겠습니다.&lt;/p&gt;

&lt;p&gt;Mutation인 setRepos로 받은 repos를 tableView에 바인딩 해주는 모습을 볼 수 있습니다.&lt;/p&gt;

&lt;h4 id=&quot;3-view에-reactor-넣어주기&quot;&gt;3. View에 Reactor 넣어주기&lt;/h4&gt;

&lt;p&gt;Reactor와 View 간의 흐름을 연결해주는 것만 남았습니다. bind()는  View의 Reactor에 새로운 값이 들어왔을 때만 호출되기 때문입니다.&lt;/p&gt;

&lt;h4 id=&quot;-전체코드&quot;&gt;! 전체코드&lt;/h4&gt;

&lt;p&gt;https://github.com/ReactorKit/ReactorKit/tree/master/Examples/GitHubSearch&lt;/p&gt;

&lt;h3 id=&quot;끝으로&quot;&gt;끝으로&lt;/h3&gt;

&lt;p&gt;말로만 듣던,, ReactorKit,, 간단하게 예제를 통해 알아보았는데 아무래도 아직 미숙한 점이 많아 틀린 부분이 있을 수도 있습니다. 틀린 부분이 있으면 프로필에 기재된 이메일로 피드백 주시면 감사하겠습니다 :) MVVM으로 프로젝트를 몇개 진행했었는데&lt;/p&gt;

&lt;p&gt;바인딩 방법의 통일을 주니 협업시에도 유용하게 쓰일 것 같아 기대가 됩니다! 더 공부해서 프로젝트에 도입해야겠어요..!&lt;/p&gt;

&lt;h4 id=&quot;출처&quot;&gt;출처&lt;/h4&gt;

&lt;p&gt;https://medium.com/styleshare/reactorkit-시작하기-c7b52fbb131a&lt;/p&gt;

&lt;p&gt;https://eunjin3786.tistory.com/100&lt;/p&gt;</content><author><name>Gayo</name></author><category term="ReactorKit" /><category term="-ReactorKit이란?" /><category term="-ReactorKit의" /><category term="데이터" /><category term="흐름" /><category term="-ReactorKit을" /><category term="써야하는" /><category term="이유?" /><category term="-예제로" /><category term="보는" /><category term="실전" /><category term="연습!" /><category term="-끝으로" /><summary type="html"></summary></entry><entry><title type="html">Welcome to Playground!</title><link href="https://ga-yo.github.io/jekyll/update/first-post/" rel="alternate" type="text/html" title="Welcome to Playground!" /><published>2021-01-26T12:26:28+00:00</published><updated>2021-01-26T12:26:28+00:00</updated><id>https://ga-yo.github.io/jekyll/update/first-post</id><content type="html" xml:base="https://ga-yo.github.io/jekyll/update/first-post/"></content><author><name>Gayo</name></author><category term="jekyll" /><category term="update" /><summary type="html"></summary></entry></feed>