<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>무과장의 개발로 개발</title>
    <description>개발로 개발하는 개발자 무과장 블로그입니다. :)</description>
    <link>https://jmkim0213.github.io/</link>
    <atom:link href="https://jmkim0213.github.io/sitemap.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 14 Apr 2019 07:31:39 +0000</pubDate>
    <lastBuildDate>Sun, 14 Apr 2019 07:31:39 +0000</lastBuildDate>
    <generator>Jekyll v3.7.4</generator>
    
      <item>
        <title>[SpringBoot] SpringBoot MariaDB 연동</title>
        <description>&lt;h1 id=&quot;서론&quot;&gt;서론&lt;/h1&gt;
&lt;p&gt;SpringBoot와 MaridDB를 연동하기 위한 설정 기록용 글입니다 :)&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;jdbc-플러그인-설치&quot;&gt;JDBC 플러그인 설치&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;build.gradle파일에 의존성 추가&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;dependencies {&lt;br /&gt;
  …&lt;br /&gt;
  …&lt;br /&gt;
  …&lt;br /&gt;
  compile(“org.mariadb.jdbc:mariadb-java-client”)&lt;br /&gt;
}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;application-설정&quot;&gt;Application 설정&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;src/main/resources/application.properties 파일에 다음 내용 추가&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;spring.datasource.driverClassName=org.mariadb.jdbc.Driver&lt;br /&gt;
spring.datasource.url=jdbc:mariadb://{host}:{port}/{db_name}&lt;br /&gt;
spring.datasource.username={user_name}&lt;br /&gt;
spring.datasource.password={password}&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sun, 14 Apr 2019 07:30:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/springboot/2019/04/14/setting_maria_db.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/springboot/2019/04/14/setting_maria_db.html</guid>
        
        
        <category>SpringBoot</category>
        
      </item>
    
      <item>
        <title>[AWS] Tomcat 설치 &amp; 설정 및 War 배포 (with yum)</title>
        <description>&lt;h1 id=&quot;서론&quot;&gt;서론&lt;/h1&gt;
&lt;p&gt;개인 프로젝트를 진행하면서 Spring Web Service를 EC2에 Deploy하기 위해 Tomcat을 설치했습니다.&lt;br /&gt;
간단하게 기록용으로 글을 작성합니다 :)&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;jdk-설치하기&quot;&gt;JDK 설치하기&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;JDK8 설치&lt;br /&gt;
$ yum list | grep openjdk&lt;br /&gt;
$ sudo yum install java-1.8.0-openjdk&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;기존 버전 설치되어있을 시&lt;br /&gt;
$ sudo /usr/sbin/alternatives –config java&lt;br /&gt;
$ sudo yum remove java-1.7.0-openjdk&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;버전확인&lt;br /&gt;
$ java -version&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;톰캣-설치하기&quot;&gt;톰캣 설치하기&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;명령어&lt;br /&gt;
$ yum list | grep tomcat8&lt;br /&gt;
$ sudo yum install tomcat8&lt;br /&gt;
$ sudo yum install tomcat8-admin-webapps&lt;br /&gt;
$ sudo yum install tomcat8-webapps&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;관리자-로그인-기능-활성화&quot;&gt;관리자 로그인 기능 활성화&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;명령어&lt;br /&gt;
$ cd /usr/share/tomcat8/conf/Catalina/localhost&lt;br /&gt;
$ sudo vim ./manager.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Context&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;privileged=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;antiResourceLocking=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;false&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;docBase=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;${catalina.home}/webapps/manager&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt; 
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;Valve&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;className=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;org.apache.catalina.valves.RemoteAddrValve&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;allow=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;^.*$&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Context&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;톰켓-관리자-설정&quot;&gt;톰켓 관리자 설정&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;명령어&lt;br /&gt;
$ cd /usr/share/tomcat8/conf&lt;br /&gt;
$ sudo vim ./tomcat-users.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;톰캣-실행하기&quot;&gt;톰캣 실행하기&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;명령어&lt;br /&gt;
$ sudo service tomcat8 start&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;war파일-배포하기&quot;&gt;War파일 배포하기&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;http://{host}:8080/manager/html&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;
</description>
        <pubDate>Sun, 31 Mar 2019 13:30:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/aws/springboot/tomcat/2019/03/31/install_tomcat.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/aws/springboot/tomcat/2019/03/31/install_tomcat.html</guid>
        
        
        <category>AWS</category>
        
        <category>SpringBoot</category>
        
        <category>Tomcat</category>
        
      </item>
    
      <item>
        <title>[Github] RestApiProtocolSample (POP + RxSwift + Alamofire + Codable)</title>
        <description>&lt;h1 id=&quot;서론&quot;&gt;서론&lt;/h1&gt;
&lt;p&gt;이번에는 제가 개인적으로 사용하기 위한 Network 모듈을 소개해보겠습니다.
최대한 POP하도록 구성해보았으니 참고하실분들은 참고하시고, 개선할 점이 있으시면 언제든 풀리퀘스트 부탁드립니다 :)&lt;/p&gt;

&lt;p&gt;Github: &lt;a href=&quot;https://github.com/jmkim0213/RestApiProtocolSample&quot;&gt;https://github.com/jmkim0213/RestApiProtocolSample&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;pop&quot;&gt;POP&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;프로토콜 지향적으로 설계하기 위해 RestApiProtocol을 구현했습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;rxswift&quot;&gt;RxSwift&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;통신에 대한 결과 (성공, 실패 등)을 bind하여 처리하기위해 사용되었습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;alamofire&quot;&gt;Alamofire&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;네트워크 통신을 직접적으로 하기 위해 사용한 라이브러리 입니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;codable&quot;&gt;Codable&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;마샬링을 위해 Swift에서 기본적으로 제공되는 Codable을 사용했습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;구성&quot;&gt;구성&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;protocol &lt;strong&gt;RestApiProtocol&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;pop로 구현한 통신 프로토콜&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;enum &lt;strong&gt;RestResult&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;통신결과에 대한 열거형 (성공/실패)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;enum &lt;strong&gt;RestMethod&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;HttpMethod + Multipart 열거형&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;struct &lt;strong&gt;RestUploadFile&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;업로드할 파일에 대한 구조체&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;RestRunnable&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;마샬링을 Concurrent하게 처리하기 위한 유틸성 클로저&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;class &lt;strong&gt;RestApiQueue&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;DataRequest 관리(취소)를 위해 구현한 객체&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;
</description>
        <pubDate>Tue, 19 Mar 2019 14:00:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/ios/swift/github/2019/03/19/RestApiProtocolSample.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/ios/swift/github/2019/03/19/RestApiProtocolSample.html</guid>
        
        
        <category>iOS</category>
        
        <category>Swift</category>
        
        <category>Github</category>
        
      </item>
    
      <item>
        <title>[Plan] 앞으로의 공부계획</title>
        <description>&lt;h1 id=&quot;서론&quot;&gt;서론&lt;/h1&gt;
&lt;p&gt;요즘 이직준비와 그에 따른 인수인계 그리고 기존 프로젝트 리팩토링을 진행 중이라 정신없이 바쁜 하루하루를 보내고 있습니다.&lt;/p&gt;

&lt;p&gt;글을 올린지도 한참됐고해서, 현재 관심있는 분야와 공부 중 또는 앞으로 공부할 것들을 정리해봤습니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;ios-ui-architecture&quot;&gt;iOS UI Architecture&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;MVVM-C&lt;/li&gt;
  &lt;li&gt;VIPER&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ios-rxswift&quot;&gt;iOS RxSwift&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Operator&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;aws--springboot--maria-db&quot;&gt;AWS + SpringBoot + Maria DB&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;업무 외 팀 프로젝트 진행 중&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;그외-관심분야&quot;&gt;그외 관심분야&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Python&lt;/li&gt;
  &lt;li&gt;Machine Learning&lt;/li&gt;
  &lt;li&gt;Django&lt;/li&gt;
  &lt;li&gt;Golang&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 10 Mar 2019 16:30:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/plan/2019/03/10/plan.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/plan/2019/03/10/plan.html</guid>
        
        
        <category>Plan</category>
        
      </item>
    
      <item>
        <title>[Swift] class와 struct 그리고 Copy On Write</title>
        <description>&lt;h1 id=&quot;서론&quot;&gt;서론&lt;/h1&gt;
&lt;p&gt;Swift로 데이터의 집합을 표현하는 방법으로는 struct, class, tuple, array등 다양합니다.
오늘은 이 중에서 주로 데이터 모델을 작성할때 사용하는 struct와 class에 대해 알아 보고자 합니다.&lt;/p&gt;

&lt;p&gt;class와 struct는 둘 다 Property와 Function을 가지고 있으며, 프로토콜을 구현할 수 있는 공통점이 있는 타입입니다. 
하지만 근본적으로 두 타입은 많이 다릅니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;class&quot;&gt;Class&lt;/h1&gt;
&lt;p&gt;class는 참조타입(Reference Type)으로 Heap Memory 공간에 할당되며, 메모리에 할당된 class는 인스턴스 또는 객체라고 불리고 있습니다. 그리고 그 인스턴스를 참조(또는 가리키는)하는 변수를 참조변수라고 합니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;참조변수는 대입연산자(=)사용시 참조하는 인스턴스의 참조 값을 복사합니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;// class&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// property&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;foo1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// 새로운 instance 생성 후 참조변수 foo1가 참조하도록 참조 값 대입&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;foo2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo1&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// foo1의 참조 값을 foo2에 대입&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/4909483/52785580-a783af00-309b-11e9-9c8d-cf8eadc32554.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;struct&quot;&gt;Struct&lt;/h1&gt;
&lt;p&gt;struct는 값 타입(Value Type)으로 Stack, Heap, Data Memory 공간에 할당될 수 있습니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;Struct타입의 변수는 대입연산자(=)사용시 소유한 모든 Property의 값을 복사합니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// struct&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// property&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;foo1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// 새로운 구조체(foo1) 생성&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;foo2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo1&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// 새로운 구조체(foo2) 생성 후 foo1의 값을 대입&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/4909483/52786090-4230bd80-309d-11e9-8b2f-ffa1fa3c3bff.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;데이터-모델에서의-class&quot;&gt;데이터 모델에서의 class&lt;/h1&gt;
&lt;p&gt;참조타입인 class를 데이터 모델로 사용한다면, 한 인스턴스에 대해 많은 참조가 존재하게되어 인스턴스의 데이터 변경시 참조하는 모든 곳이 영향을 받아 의도치 않은 문제가 발생 할 수 있습니다.&lt;/p&gt;

&lt;p&gt;좀 더 풀어서 이야기해보겠습니다. &lt;br /&gt;
Foo와 Bar가 동일한 인스턴스 fooBar를 참조하고 있고, Foo의 어느 함수 내에서 fooBar 상태를 변경했다고 가정해봅시다. Bar도 fooBar를 참조해서 사용하고 있기때문에, Foo에서 변경된 fooBar상태 변경으로 인해 Bar에서 의도치 않은 문제가 발생 할 수도 있습니다.&lt;/p&gt;

&lt;p&gt;또한, 이렇게 발생된 문제는 참조가 많은 경우에 문제의 발생지를 찾기 어려워져 디버깅을 하기가 쉽지 않습니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;데이터-모델에서의-struct&quot;&gt;데이터 모델에서의 struct&lt;/h1&gt;
&lt;p&gt;값 타입인 struct를 데이터 모델로 사용한다면, 위에서 거론한 class의 문제 점을 해결 할 수 있습니다.
struct는 대입시 참조가 아닌 값을 복사하기 때문에, struct의 값을 변경한다해도 그 값이 다른 곳에 영향을 주지 않기 때문입니다.&lt;/p&gt;

&lt;p&gt;하지만 struct의 덩치가 커지게되면 struct간 대입연산(=)시에 모든 값이 복사되어야 하기 때문에 속도적인 면에서 큰 비용이 발생합니다. 또한 struct의 값이 변경될 필요가 없음에도 불구하고 대입연산시 매번 새로운 메모리 공간을 할당해 프로퍼티를 복사하므로 불필요한 메모리 할당이되는 문제가 발생합니다.&lt;/p&gt;

&lt;p&gt;위 문제는 Copy on write라는 개념을 도입해 해결이 가능합니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;copy-on-write&quot;&gt;Copy on write&lt;/h3&gt;
&lt;p&gt;Copy on write (이하 COW)는 데이터 복사시 실제로 값을 복사되지 않고, 동일한 값을 참조하다가 데이터 변경이 발생될 시에 복사해 값을 변경하는 기법입니다.&lt;/p&gt;

&lt;p&gt;Swift에서는 원시타입 구조체(Int, Double, String)와 Array, Set, Dictionary등 컬렉션 구조체에 이미 구현되어있습니다.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;arr1&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;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// [Int]배열이 생성됩니다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;arr2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr1&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// 이 경우 실제 복사가 일어나지 않고, 동일한 주소를 가지게 됩니다.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;arr1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// 이때 [0, 1, 2]배열이 복사가 되며, arr1은 [0, 1, 2, 3]의 값을 가지게 되고 arr2와 다른 주소를 가지게 됩니다.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;사용자-정의-구조체에서의-cow&quot;&gt;사용자 정의 구조체에서의 COW&lt;/h1&gt;
&lt;p&gt;사용자 정의 구조체에는 COW가 구현되어있지 않기 때문에 필요하다면 구현해줘야 합니다.&lt;br /&gt;
주석으로 간단한 예제를 설명하면서 COW를 구현해보도록 하겠습니다.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// 일단 사용자 정의 구조체 UserData를 정의합니다.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UserData&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;intValue&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;strValue&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;o&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;cm&quot;&gt;/*
대입연산에 의해 즉각적으로 프로퍼티 복사가 발생하는 것을 막기 위해 
참조타입인 Class를 이용해 UserData를 한번 wrapping 해줄 필요가 있습니다.
또한, UserData말고도 다른 타입에 대해 범용적으로 활용할 수 있도록 
Generic(&amp;lt;T&amp;gt;)으로 데이터타입에 대한 유연성을 부여해줍니다.
*/&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DataWrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&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;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&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;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&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;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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
  DataWrapper를 제어해줄 CowData 구조체를 선언합니다.
*/&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CowData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&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;c1&quot;&gt;// Data Wrapper&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dataWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DataWrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;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;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&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;dataWrapper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DataWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&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;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&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;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataWrapper&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;set&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isKnownUniquelyReferenced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&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;dataWrapper&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;c1&quot;&gt;// dataWrapper에 대한 참조가 Uniquely하지 않으면 새로운 Wrapper를 생성하여 값을 대입해줍니다.&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;dataWrapper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DataWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newValue&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;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// dataWrapper에 대한 참조가 Uniquely하다면 기존 Wrapper에 대해서 struct 값을 대입해줍니다.&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;dataWrapper&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newValue&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;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cowData1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CowData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UserData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cowData1&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;i'm UserData1&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// cowData2의 dataWrapper는 cowData1와 동일한 참조를 가지게 됩니다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cowData2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cowData1&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;!! cowData2의 dataWrapper는 cowData1와 동일한 참조를 가지고 있습니다.&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;s&quot;&gt;&quot;cowData1.data.strValue: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cowData1&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strValue&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;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;cowData2.data.strValue: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cowData2&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strValue&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)\n&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;c1&quot;&gt;// cowData2의 dataWrapper가 새로운 struct값과 함께 새롭게 할당됩니다.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cowData2&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;i'm UserData2&quot;&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;!! cowData2의 dataWrapper는 cowData1와 다른 참조를 가지고 있습니다.&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;s&quot;&gt;&quot;cowData1.data.strValue: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cowData1&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strValue&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;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;cowData2.data.strValue: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cowData2&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strValue&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)\n&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;/figure&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;결과화면&quot;&gt;결과화면&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/4909483/52954611-f8621300-33cd-11e9-94e6-f7d9445764d3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;참고: &lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html&quot;&gt;https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;
</description>
        <pubDate>Mon, 18 Feb 2019 12:30:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/ios/swift/2019/02/18/copy_on_write.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/ios/swift/2019/02/18/copy_on_write.html</guid>
        
        
        <category>iOS</category>
        
        <category>Swift</category>
        
      </item>
    
      <item>
        <title>[Swift] 강한참조와 약한참조 (strong vs weak vs unowned)</title>
        <description>&lt;h1 id=&quot;강한참조-vs-약한참조&quot;&gt;강한참조 vs 약한참조&lt;/h1&gt;
&lt;p&gt;ARC(Automatic Reference Counting)는 &lt;code class=&quot;highlighter-rouge&quot;&gt;컴파일 시점&lt;/code&gt;에 retain relase 와 같은 메모리 관리 메소드를 자동으로 삽입해줍니다. 가비지 컬렉터(Garbage collection)와 달리 참조사이클을 자동으로 처리하지 않기 때문에, 객체에 대해 강한참조가 남아 있는한 해당 객체는 메모리 해제가 되지 않게 됩니다.&lt;/p&gt;

&lt;p&gt;따라서, 서로 다른 객체가 서로를 강하게 참조하게 되면 &lt;code class=&quot;highlighter-rouge&quot;&gt;순환참조가 발생해 메모리 누수(Memory Leak)&lt;/code&gt;가 발생됩니다. 아래의 코드는 Foo와 Bar가 서로를 강하게 참조하여 순환참조가 발생되는 코드입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/4909483/52545320-e8f52f80-2df9-11e9-992b-66ddfcf3291b.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&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;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bar&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;Bar&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;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&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;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&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;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// Foo가 Bar를 강하게 참조&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// Bar가 Foo를 강하게 참조&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;p&gt;그럼 순환참조를 방지하려면 어떻게 해야할까요?&lt;br /&gt;
바로 Foo나 Bar중 하나가 강한참조가 아닌 약한참조를 가지면 됩니다.&lt;br /&gt;
약한참조는 &lt;code class=&quot;highlighter-rouge&quot;&gt;weak&lt;/code&gt; 또는 &lt;code class=&quot;highlighter-rouge&quot;&gt;unowned&lt;/code&gt; 키워드를 사용합니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;weak&lt;/code&gt;와 &lt;code class=&quot;highlighter-rouge&quot;&gt;unowned&lt;/code&gt; 키워드를 지정한 참조변수는 참조하는 객체에 대해서 참조계수를 증가시키지 않기 때문에 순환참조를 방지할 수 있습니다. (약한참조)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/4909483/52551571-62077d80-2e20-11e9-94f7-67bee59cdf3e.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&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;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bar&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;Bar&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;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&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;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foo&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;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// Foo가 Bar를 강하게 참조&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// Bar가 Foo를 약하게 참조&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;
&lt;h1 id=&quot;weak-vs-unowned&quot;&gt;weak vs unowned&lt;/h1&gt;
&lt;p&gt;weak와 unowned는 모두 약한참조를 위한 키워드로, 참조하는 객체의 참조계수에 영향을 주지 않습니다.&lt;br /&gt;
 그럼 이 둘은 어떤 차이가 있을까요?&lt;/p&gt;

&lt;p&gt;weak키워드는 optional에 사용할 수 있으며, unowned는 non-optional인 경우에만 사용 가능합니다.&lt;br /&gt;
따라서 unowned는 옵셔널 추출이 필요하지 않지만, 참조하는 객체의 메모리가 해제된 상태에서 객체에 메세지를 보내면 bad access에러가 발생됩니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;if. 참조하는 객체의 참조계수가 0이 되어 메모리가 해제되는 경우.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;weak는 참조 값이 nil로 대체됩니다.&lt;br /&gt;
 unowned는 참조 값이 그대로 유지됩니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;p&gt;weak와 unowned는 클로저에서의 메모리 누수를 방지 하기 위해 캡쳐리스트에서도 사용될 수 있습니다.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unownedClosure&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;n&quot;&gt;unowend&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;cm&quot;&gt;/*  옵셔널 추출이 필요치 않으나, 
      self의 메모리가 해제된 상태에서 'self.doProccess()'을 수행하게 되면 에러가 발생됩니다! */&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;nf&quot;&gt;doProccess&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;weakClosure&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;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;k&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// 옵셔널 추출과정이 필요하지만 더 안전합니다.&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;self&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;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;nf&quot;&gt;doProccess&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;/figure&gt;

&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;unowned는 해제된 객체에 접근이 가능해 에러를 발생 시킬 수 있으므로,&lt;br /&gt;
약한참조가 필요한 경우 weak 키워드만을 사용하고, guard let(또는 if let) 구문을 통해 안전하게 옵셔널 추출하는 것을 권장합니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;p&gt;참고: &lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html&quot;&gt;https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;
</description>
        <pubDate>Fri, 08 Feb 2019 10:30:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/ios/swift/2019/02/08/weak_Vs_unowned.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/ios/swift/2019/02/08/weak_Vs_unowned.html</guid>
        
        
        <category>iOS</category>
        
        <category>Swift</category>
        
      </item>
    
      <item>
        <title>[iOS] state 별로 UIButton의 백그라운드 컬러변경하는 방법</title>
        <description>&lt;p&gt;UIButton 컴포넌트에는 normal, highlighted, disabled, selected 등 여러 상태에 따른 이미지를 지정할 수 있습니다.&lt;br /&gt;
그런데 왜 그런지는 모르겠지만 당연하게 있어야할거 같은 backgroundColor를 각 상태에 맞게 지정하는 방법을 지원하지 않습니다.&lt;/p&gt;

&lt;p&gt;이에 약간의 꼼수를 부려 BackgroundColor를 상태 별로 지정하는 코드를 소개해보자 합니다.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIKit&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIButton&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setBackgroundColor&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;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIColor&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;nv&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIControl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;State&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;UIGraphicsBeginImageContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;CGSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&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;context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIGraphicsGetCurrentContext&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;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setFillColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cgColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fill&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;nv&quot;&gt;x&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;nv&quot;&gt;y&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;nv&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&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;backgroundImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIGraphicsGetImageFromCurrentImageContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;UIGraphicsEndImageContext&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;nf&quot;&gt;setBackgroundImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backgroundImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&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;/figure&gt;

&lt;p&gt;코드는 간단합니다. ImageContext를 생성하여 색으로 채운 뒤 이미지를 생성합니다.&lt;br /&gt;
그리고 생성된 이미지를 setBackgroundImage함수를 이용해 각 상태별로 지정합니다.&lt;/p&gt;

&lt;p&gt;위 코드 작성이 끝나면 아래와 같이 사용하면 됩니다.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setBackgroundColor&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;red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;for&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;normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setBackgroundColor&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;blue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;for&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;selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setBackgroundColor&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;gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;for&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;disabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 05 Feb 2019 14:50:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/ios/swift/ui/2019/02/05/button_background.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/ios/swift/ui/2019/02/05/button_background.html</guid>
        
        
        <category>iOS</category>
        
        <category>Swift</category>
        
        <category>UI</category>
        
      </item>
    
      <item>
        <title>[iOS] Swift버전 변경 시 pod프로젝트 빌드 안되는 이슈 해결방법</title>
        <description>&lt;p&gt;Swift언어의 버전은 금방 업데이트가 되나 우리가 사용하는 라이브러리들은 언어에 대한 대응이 늦을 때가 많습니다.&lt;br /&gt;
따라서 진행중인 프로젝트의 Swift버전을 올리게 되면 pod 프로젝트의 버전도 함께 올라가게 되어 빌드가 실패하는 경우가 종종 발생됩니다.&lt;/p&gt;

&lt;p&gt;2019년 2월 5일 기준 Swift버전은 4.2까지 공개가 되었습니다.&lt;br /&gt;
Swift5 공개도 얼마 안남았고, 제가 Swift4.0에서 4.2로 프로젝트 세팅을 변경했을때 발생한 이슈에 대해 해결방법을 제시하고자 합니다.&lt;/p&gt;

&lt;p&gt;해결방법은 의외로 간단합니다.&lt;br /&gt;
podfile 하단에 아래의 코드를 작성해서 pod 프로젝트의 Swift버전을 강제로 수정해줍니다.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;post_install &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; |installer|
    installer.pods_project.targets.each &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; |target|
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'$lib_name'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;.include? target.name
            target.build_configurations.each &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; |config|
                config.build_settings[&lt;span class=&quot;s1&quot;&gt;'SWIFT_VERSION'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'4.0'&lt;/span&gt;
            end
        end
    end
end&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;빌드 타겟이 문제가 될시는 다음 코드도 함께 삽입해줍니다.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;    config.build_settings[&lt;span class=&quot;s1&quot;&gt;'IPHONEOS_DEPLOYMENT_TARGET'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'9.0'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 05 Feb 2019 14:10:00 +0000</pubDate>
        <link>https://jmkim0213.github.io/ios/cocoapods/2019/02/05/cocoapods.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/ios/cocoapods/2019/02/05/cocoapods.html</guid>
        
        
        <category>iOS</category>
        
        <category>CocoaPods</category>
        
      </item>
    
      <item>
        <title>[iOS] NotificationCenter 가독성 높이기 (with RxSwift + Protocol)</title>
        <description>&lt;p&gt;NotificationCenter는 전역적인 이벤트를 처리하기 위해 사용되는 유용한 클래스입니다.&lt;br /&gt;
그러나 NotificationName을 제대로 정리하지 않으면, 가독성과 유지보수가 어려워지는 문제점이 있습니다.&lt;br /&gt;
이번 포스트에서는 Protocol + Enum + RxSwift를 활용해서 NotificationCenter를 쉽게 사용하는 방법을 소개해보자 합니다 :)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;일단 NotificationCenterProtocol를 작성합니다.&lt;br /&gt;
Notification.Name을 반환하는 프로퍼티를 하나 선언한 뒤에 옵저버 등록과 이벤트 post 기능을 구현합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foundation&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RxSwift&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NotificationCenterProtocol&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;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Notification&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&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;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NotificationCenterProtocol&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addObserver&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;Observable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&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;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;kt&quot;&gt;NotificationCenter&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;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;nf&quot;&gt;notification&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;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;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&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;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;object&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;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;kt&quot;&gt;NotificationCenter&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;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;post&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;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;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;userInfo&lt;/span&gt;&lt;span class=&quot;p&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;위와 같이 기본 프로토콜을 정의 한 후에 Enum 타입으로 프로토콜을 구현해줍니다.&lt;br /&gt;
여기서 Custom Notification Name이 겹치지 않게 프로토콜을 구현한 Enum타입의 이름을 네임스페이스로 활용합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foundation&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIKit&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ApplicationNotificationCenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NotificationCenterProtocol&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;n&quot;&gt;willEnterForeground&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;didReceiveMemoryWarning&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;custom&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;var&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;Notification&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Name&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;k&quot;&gt;self&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;willEnterForeground&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;UIApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;willEnterForegroundNotification&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;didReceiveMemoryWarning&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;UIApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;didReceiveMemoryWarningNotification&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;custom&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;Notification&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ApplicationNotificationCenter.custom&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;Enum타입을 구현했으면 다음과 같이 이벤트를 옵저빙 할 수 있게 됩니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kt&quot;&gt;ApplicationNotificationCenter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addObserver&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;bind&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&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;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as?&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&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;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;object&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;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&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;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;이벤트 발생 시점에 다음과 같이 작성하면 NotificationCenter를 통해 이벤트를 Post할 수 있게 됩니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;kt&quot;&gt;ApplicationNotificationCenter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;custom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;custom event발생!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</description>
        <pubDate>Tue, 05 Feb 2019 12:32:58 +0000</pubDate>
        <link>https://jmkim0213.github.io/ios/swift/rxswift/2019/02/05/notificationcenter.html</link>
        <guid isPermaLink="true">https://jmkim0213.github.io/ios/swift/rxswift/2019/02/05/notificationcenter.html</guid>
        
        
        <category>iOS</category>
        
        <category>Swift</category>
        
        <category>RxSwift</category>
        
      </item>
    
  </channel>
</rss>
