<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Kaizen Note✍🏻</title>
        <link>https://velog.io/</link>
        <description>개발 공부하고 있어요!</description>
        <lastBuildDate>Sat, 14 Mar 2020 17:40:02 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Kaizen Note✍🏻</title>
            <url>https://velog.velcdn.com/images/dev-lena/profile/4733bcde-65c3-490a-86c4-a202fb20f7d7/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Kaizen Note✍🏻. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev-lena" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.14]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.14</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.14</guid>
            <pubDate>Sat, 14 Mar 2020 17:40:02 GMT</pubDate>
            <description><![CDATA[<h3 id="오늘-한-일">오늘 한 일</h3>
<ol>
<li>집이 가까운 동료(밤고구마🍠님)와 만나 모각코를 했다.</li>
<li>기존에 상위 모듈에서 값을 가져와서 다른 데이터 구조를 만들어서 비교했는데, 이 점에 대해서 피드백을 받아서 하위 모듈(Card 또는 Rank) 그 자체에서 비교하고 판단하도록 수정했다. 다음에는 객체 역할에 대해서 더 고민해보고 생각해봐야겠다.</li>
<li>Compareable 프로토콜에 대해서 알게됐다. (내일 정리해서 올릴 계획)</li>
<li>이전 PR에서 마스터가 피드백 해주셨던 부분을 마무리 짓고 PR을 보냈다. 
이런 과정을 거쳐서
<img src="https://images.velog.io/images/dev-lena/post/1b36e6a0-c7ff-4f25-b787-a9986eeab0de/image.png" alt="">
드디어 메달을 달았다!
<img src="https://images.velog.io/images/dev-lena/post/8e4e85a8-1d99-4f6a-b9eb-b33db72eb697/image.png" alt=""></li>
</ol>
<h3 id="배운-점">배운 점</h3>
<ol>
<li><p>뷰 객체를 서브클래스로 만들 때는 init 메소드를 어떤 것을 쓰더라도 동일한 결과가 나오도록 만드는 게 좋다. init(coder:)를 당장 사용하지 않더라도 다른 init과 동일하게 초기화가 되도록 만들어야 한다.</p>
<pre><code class="language-swift">override init(frame: CGRect) { // by code
    super.init(frame: frame)
    configure()
}

required init(coder: NSCoder) { // by storyBoard
    super.init(coder: coder)
    configure()
}
// ... 생략</code></pre>
</li>
<li><p>view를 감추는 isHidden에 대해서 알게됐다.
기본적으로 view는 isHidden = false 상태이고 true로 바꾸면 보이지 않는다.
화면에서 공간은 차지하는데 보이지 않는게 아니라 공간 자체를 차지하지 않고 보이지도 않는다.</p>
</li>
<li><p>Compareable 프로토콜에 대해서 알게 됐고 사용해봤다.</p>
</li>
</ol>
<h3 id="느낀-점">느낀 점</h3>
<p>오랜만에 남산 아랫길과 한강진쪽을 걸었는데 하늘이 너무 예뻐서 기분이 좋았다. 안되는거 붙잡고 하루종일 앉아만있는것 보다 가까운 산책이라도 다니기 시작해야겠다. 사실 이번 미션에 대해서 아무래도 초반보다는 의지가 많이 떨어졌는데, 그래도 jk가 내가 보낸 PR에 대해서 친절하고 섬세하게 피드백해주셔서 마무리지을 수 있었던 것 같다.(아직 PR 답은 못받았지만 ㅎ) 마스터분들도 그렇고 동료분들도 그렇고 좋은 분들에게 또 좋은 사람들과 배울 수 있어서 너무 좋다.☺️</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.13]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.13</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.13</guid>
            <pubDate>Sat, 14 Mar 2020 04:38:12 GMT</pubDate>
            <description><![CDATA[<h3 id="오늘-한-일">오늘 한 일</h3>
<ol>
<li>Hashable 프로토콜에 대한 정리를 마무리하고 글을 올렸다
<a href="https://velog.io/@dev-lena/Hashable-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C">https://velog.io/@dev-lena/Hashable-프로토콜</a></li>
<li>jk가 나눠준 주간 회고 양식을 써내려가면서 한 주를 돌아봤다.</li>
</ol>
<h3 id="알게된-점">알게된 점</h3>
<ol>
<li>Hashable 프로토콜에 대해 정리한 글을 마무리 하려고 하니까 이전에 초고(?)를 썼을 때 보다 더 자세하게 알아봤다.</li>
</ol>
<h3 id="주간회고">주간회고</h3>
<p><img src="https://images.velog.io/images/dev-lena/post/cf9eefb2-99da-4761-9619-741ef6e51698/image.png" alt=""></p>
<h3 id="느낀점">느낀점</h3>
<p>다음주 페어 프로그래밍을 하는데 벌써부터 많이 많이 정말 많이 😢걱정이 되지만 그래도 오늘 최선을 다하자.
약간 오그라들긴 하지만 기억하려고 남겨놓는 내가 좋아하는 말들.
<img src="https://images.velog.io/images/dev-lena/post/441500f7-2589-424d-a5ea-39c40f418ae6/image.png" alt="">
<img src="https://images.velog.io/images/dev-lena/post/d98a4a04-6d17-495d-b9f9-b0d683820f77/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Hashable 프로토콜]]></title>
            <link>https://velog.io/@dev-lena/Hashable-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</link>
            <guid>https://velog.io/@dev-lena/Hashable-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</guid>
            <pubDate>Fri, 13 Mar 2020 10:30:01 GMT</pubDate>
            <description><![CDATA[<h2 id="hashable">Hashable?</h2>
<ul>
<li><strong>정수 해시 값을 제공</strong>하고 Dictionary의 키가 될 수 있는 타입입니다.
(Dictionary의 key value는 Hashable 프로토콜을 만족하는 타입이여야 합니다.)</li>
<li>다르게 말하면 value가 hashable해야할 때, Hashable 프로토콜을 채택해서 구현해주면 hashable이 보장된 정수 해시 값을 제공합니다.</li>
<li>구조체(Strucrue)의 저장프로퍼티는 모두 Hashable을 준수해야합니다.</li>
<li>열거형(Enumeration)의 모든 연관값(associated values)은 모두 Hashable을 준수해야합니다.</li>
</ul>
<h3 id="hashable이-필요한-경우">Hashable이 필요한 경우?</h3>
<p>Dictionary의 key에 들어갈 타입을 기본 데이터로 정해주면 Hashable을 만족하지 않는다는 에러는 만나지 않습니다. 왜냐하면 String,Int,Bool 등 기본 데이터 타입들은 모두 Hashable protocol을 만족하고 있기 때문이죠! 그런데 커스텀 타입을 key의 타입으로 정하면 에러를 만날 수 있습니다. 아래에 예제 코드로 설명해볼께요.</p>
<h3 id="에러가-나는-예제-코드">에러가 나는 예제 코드</h3>
<pre><code class="language-swift">// 에러가 나는 코드

class Participant{
 private var name : String
 private var age : Int

 init(_ name: String, _ age: Int){
 self.name = name
 self.age = age
 }
}

class Student: Participant{
  private var admissionYear : Int 
}

enum SpecializedField {
  case Math, ComputerScience
}

class Professor: Participant{
  private var specializedField: SpecializedField
}

class Lecture{
 private var participantList = [Participant:Bool]() // 딕셔너리
///... 이하 생략
}</code></pre>
<p>만약 이렇게만 한다면</p>
<p><img src="https://images.velog.io/images/dev-lena/post/6e3c83b6-5cb7-4de0-8791-0bfeeb26b277/image.png" alt="">
이런 에러를 만날 수 있습니다. 😢</p>
<p> 에러 메세지를 보면 Dictionary에서 key의 타입으로 설정해준 Participant가 Hashable하지 않다고 나옵니다. 그렇다면 이제 Participant를 Hashable하도록 만들어주면 됩니다!</p>
<h3 id="정상적으로-돌아가는-예제-코드">정상적으로 돌아가는 예제 코드</h3>
<pre><code class="language-swift">
class Participant{
 private var name : String
 private var age : Int

 init(_ name: String, _ age: Int){
 self.name = name
 self.age = age
 }
}

extension Participant : Hashable{
    static func == (lhs: Participant, rhs: Participant) -&gt; Bool {
        return lhs.name == rhs.name &amp;&amp; lhs.age == rhs.age 
    }

    //* 여기
    func hash(into hasher: inout Hasher) {
       hasher.combine(name)
       hasher.combine(age)
    }
}

enum SpecializedField {
  case Math, ComputerScience
}

class Professor: Participant{
  private var specializedField: SpecializedField
}
extension Professor : Hashable{
    static func == (lhs: Professor, rhs: Professor) -&gt; Bool {
        return lhs.specializedField == rhs.specializedField 
    }

    //* 여기
    func hash(into hasher: inout Hasher) {
       hasher.combine(specializedField)
    }
}

class Student : Participant{
  private var admissionYear : Int 
}

extension Student : Hashable{
    static func == (lhs: Student, rhs: Student) -&gt; Bool {
        return lhs.admissionYear == rhs.admissionYear 
    }

    //* 여기
    func hash(into hasher: inout Hasher) {
       hasher.combine(admissionYear)
    }
}

class Lecture{
 private var participantList = [Participant:Bool]() // 딕셔너리
///... 이하 생략
}
</code></pre>
<p><strong>방법은, 관련된 모든 클래스에서 Hashable을 구현해주면 됩니다. 관련 클래스의 모든 저장 프로퍼티를 Hashable하도록 만들어주면 돼요!</strong></p>
<p>그럼 방법을 좀 더 살펴보죠.</p>
<p>Apple Developer Document에 있는 <code>Dictionary</code>에 들어가보니까 해쉬값을 제공하기 위한 인스턴스 메소드로 </p>
<pre><code class="language-swift">func hash(into hasher: inout Hasher)</code></pre>
<p>가 있네요. Hashable을 준수하려면 <code>hash(into:)</code>가 필수라고 되어있습니다.</p>
<p>파라미터로 <code>Hasher</code>타입의 <code>hasher</code>를 받고있죠? 문서에는 <strong>필수 구성요소들에게 주어진 hasher를 공급함으로써 value의 필수 구성요소들을 해쉬하라</strong>고 하네요! (Hashes the essential components of this value by feeding them into the given <code>hasher</code>.)</p>
<p>이 일은 위에 정상적으로 돌아가는 예제 코드에서 extension으로 Hashable을 채택한 부분에 있는 hash(into:) 메소드(&#39;* 여기&#39;표시한 곳 )가 해주는 일 같아요! </p>
<p>그럼 여기에 나오는 hasher는 뭘까요?</p>
<h3 id="hasher">Hasher?</h3>
<p>hasher는 구조체로, <strong>해당 인스턴스의 구성요소를 결합할 때 사용한다고 해요.</strong>(The hasher to use when <code>combining</code> the components of this instance.)</p>
<p>그럼 여기에 나오는 combine은 뭘까요?</p>
<h3 id="combine">combine?</h3>
<p>제네릭 인스턴스 메소드로 <strong>Hasher 구조체에서 value를 추가하는 메소드</strong>인데요.</p>
<pre><code class="language-swift">mutating func combine&lt;H&gt;(_ value: H) where H : Hashable</code></pre>
<p><strong>해셔에 주어진 값을 추가하여 그 필수적인 부분을 해셔 상태로 혼합한다고 해요.</strong>(Adds the given value to this hasher, mixing its essential parts into the hasher state.)</p>
<p>이 일은 위에 정상적으로 돌아가는 예제 코드에서 &#39;* 여기&#39;표시한 곳 안에 <code>haser.combine()</code> 이 부분에서 해주는 일 같네요.</p>
<p>제 생각에는 단순히 저장 프로퍼티만 hash 값으로 만들어 주면 하나의 객체를 이루는 요소임을 알 수 없으니까 프로퍼티들을 묶어주는 것 같아요. (혹시 아시는 분 있다면 댓글 남겨주세요!) </p>
<p>이렇게 participantList에 key로 들어갈 수 있는 커스텀 타입의 모든 저장 프로퍼티를 Hashable 하도록 만들어주면 Participant 타입을 딕셔너리의 Key 타입으로 쓸 수 있게 됩니다!</p>
<h2 id="참고한-자료">참고한 자료</h2>
<ol>
<li><a href="https://www.hackingwithswift.com/example-code/language/how-to-conform-to-the-hashable-protocol">How to conform to the Hashable protocol - Swift version: 5.1</a></li>
<li><a href="https://developer.apple.com/documentation/swift/dictionary">Dictionary - Apple Developer Document</a> </li>
<li><a href="https://developer.apple.com/documentation/swift/hashable">Hashable - Apple Developer Document</a></li>
<li>[hash(into:) - Apple Developer Document] (<a href="https://developer.apple.com/documentation/swift/dictionary/2995338-hash">https://developer.apple.com/documentation/swift/dictionary/2995338-hash</a>)</li>
<li><a href="https://developer.apple.com/documentation/swift/hasher">hasher - Apple Developer Document</a></li>
<li><a href="https://developer.apple.com/documentation/swift/hasher/2995578-combine">combine(_:) - Apple Developer Document</a></li>
</ol>
<blockquote>
<p>궁금한 점, 틀린 내용, 오타 지적, 오역 지적 등 피드백 환영합니다! 댓글로 남겨주세요!
😊 🙏</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.12]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.12</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.12</guid>
            <pubDate>Thu, 12 Mar 2020 19:29:25 GMT</pubDate>
            <description><![CDATA[<h3 id="오늘한-일">오늘한 일</h3>
<ol>
<li>어제 알아봤던 Hashable 프로토콜에 대해서 블로그에 글을 임시저장글로 남겨놨다. 내일 마무리하고 올려야지.</li>
<li>알고리즘 문제를 풀었다. </li>
<li>어쨌든 안풀리는 건 안풀리는 대까지 해서 PR 메세지에 질문을 담아 보냈다.</li>
<li>상속과 초기화, Result 타입에 대한 수업을 들었다.</li>
</ol>
<p><strong>LeetCode - MergeSortedArray</strong>
swift - 12 ms</p>
<h3 id="배운-점">배운 점</h3>
<ol>
<li>init과 convenience init, super.init에 대해서 알게됐다.</li>
<li>Result 타입이란 뭔지 처음 들어보고 설명을 들었다.</li>
</ol>
<h3 id="느낀점">느낀점</h3>
<p> 오늘은 평소보다도 2시간 정도 빨리와서 간단한 알고리즘 문제를 풀었다. 이번달에는 swift로 알고리즘을 꾸준히 풀면서 swift의 자료 구조에 대한 이해를 높이고 싶다.<br> 아침을 일찍 시작하고 느낀점은 일단 평소보다 일찍온 시간만큼 시간을 더 투자해서 뭔가를 한다는게 뿌듯했다. 하지만 아침에 일어나서 도착하기까지 과연 이렇게 피곤한 상태라도 일찍가는게 맞는가 백만번 생각했던 것 같다. 한마디로 짜증이 엄청났다. 그런데 또 하루를 보내보니까 평소에는 별거 한 것도 없는데 점심을 먹으러 나가서 오전을 버린다는 느낌이 강했는데, 한 두시간 정도 일찍 오니까 오전을 버린다는 생각은 안드는 것 같다.
 오늘부터 동료들과 아침 알고리즘을 할 사람들끼리 아침 9시까지 오기로 했고, 오늘부터 알고리즘타임을 시작했었는데, 이렇게 약속을 하고 하니까 미루지 않고 하게 되는 것 같다.
 다음주까지 iOS/ Swift 관련해서 알아보기로 한 주제에 대해서 이제부터 알아보기 시작해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.11]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.11</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.11</guid>
            <pubDate>Thu, 12 Mar 2020 01:50:24 GMT</pubDate>
            <description><![CDATA[<h3 id="오늘-한-일">오늘 한 일</h3>
<ol>
<li>피드백 받은 부분 문법 수정</li>
<li>승자에게 메달 이미지 뷰 표시되도록 구현하고 싶었지만 못함. 내일해야지.</li>
</ol>
<h3 id="배운-점">배운 점</h3>
<p>Dictionary에 Key 타입을 PokerPlayer 클래스 객체 넣으려고 하니까 Hashable을 따르지 않아서 불가능하다는 에러가 났는데, 이걸 해결하기 위해서 Hashable 프로토콜에 대해서 알아봤다. 
<img src="https://images.velog.io/images/dev-lena/post/96167fc8-97a5-4d6b-b45d-cdda194b21bc/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.10]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.10</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.10</guid>
            <pubDate>Tue, 10 Mar 2020 18:32:10 GMT</pubDate>
            <description><![CDATA[<h3 id="오늘한-일">오늘한 일</h3>
<ol>
<li>불필요한 클래스를 삭제했고 고민해봤을 때 더 적절한 곳에 메소드와 프로퍼티가 위치하도록 전체적으로 수정했다.</li>
<li>블로그에 글을 썼다.</li>
<li>어제 알게된 lazy 프로퍼티에 대해서 블로그 글을 올렸다.
<a href="https://velog.io/@dev-lena/View%EC%9D%98-lazy-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0">https://velog.io/@dev-lena/View의-lazy-프로퍼티</a></li>
</ol>
<h3 id="오늘-배운-점">오늘 배운 점</h3>
<ol>
<li>배열에서 중복을 제거할 때 Set을 사용하면 반복문을 사용하지 않고도 중복값을 제거할 수 있다.
블로그 글로 올렸다!
<a href="https://velog.io/@dev-lena/%EC%84%B8%ED%8A%B8Set%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%97%B4Array%EC%97%90%EC%84%9C-%EC%A4%91%EB%B3%B5%EA%B0%92-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0">https://velog.io/@dev-lena/세트Set으로-배열Array에서-중복값-제거하기</a></li>
<li>어떤 일을 어느 클래스에서 할지, 이 클래스는 어떤 클래스의 하위클래스로 들어가야할지 등 고민을 많이 해보자. 포커게임에서 승자를 찾을때 승자를 찾기위한 클래스를 아예 새로 만들었는데, 마스터에게 피드백을 받고 보니 기존에 있던 클래스에서 충분히 구현해도 되는 부분이었다. 처음에 어디서부터 시작해야할지 막막해서 일단 새로만들고 봐야지 했었는데, 다음에는 이런 생각과 행동을 지양해야겠다.</li>
</ol>
<h3 id="느낀점">느낀점</h3>
<ol>
<li>평소보다 한 시간정도 일찍 도착했는데, 먼저 도착한 한시간동안 오늘 어떤걸 해야하는지 구체적으로 정리하고 계획을 세우니까 오늘 하루 집중이 잘 됐었다!</li>
<li>알고리즘 공부나 문제 풀기를 이제 부터 꾸준히 해야겠다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[lazy closure를 이용한 View 초기화]]></title>
            <link>https://velog.io/@dev-lena/View%EC%9D%98-lazy-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0</link>
            <guid>https://velog.io/@dev-lena/View%EC%9D%98-lazy-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0</guid>
            <pubDate>Tue, 10 Mar 2020 18:30:26 GMT</pubDate>
            <description><![CDATA[<h3 id="lazy-"><code>lazy</code> ?</h3>
<ol>
<li><strong>지연 저장 프로퍼티</strong>. </li>
<li>호출이 있어야 값을 초기화하는데, 이 때 <strong>lazy 키워드</strong>를 사용합니다.</li>
<li>잘 사용하면 <strong>불필요한 성능저하나 공간 낭비를 줄일 수 있습니다</strong>.</li>
<li><strong>var 키워드</strong>를 사용해 변수로 정의합니다. let 키워드(상수)는 초기화 전에 인스턴스가 완전히 생성되어야 하므로 사용에 적합하지 않습니다.</li>
</ol>
<p>2번에서 호출이 있어야 값을 초기화한다는 말은,
간단히 말해서 lazy로 선언한 코드에 접근해서 실행시키기 전까지는 인스턴스화 되지 않는다고 할 수 있습니다.</p>
<h3 id="lazy-closure"><code>lazy closure</code>?</h3>
<p>아래는 UILabel을 lazy closure를 이용해 초기화한 예시.</p>
<pre><code class="language-swift">class ViewController: UIViewController {

    lazy var label: UILabel = {
        let label = UILabel(frame: .zero)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = .black
        label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
        return label
    }()

        override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(label)   
    }
}</code></pre>
<ul>
<li><p>저장 프로퍼티보다 <strong>지연 저장 프로퍼티</strong>를 사용하는 것의 주요 이점은 <strong>코드 블럭이 정확히 해당 변수의 읽기 작업이 일어날 때만 실행된다</strong>는 것입니다.</p>
</li>
<li><p>이 경우에는 ViewController 인스턴스가 생성될때 바로 lazy로 선언된 클로저(예시에서 label)가 실행되지 않습니다. 그리고 viewDidLoad()메소드 addSubView(label)에서 처음 호출할 때 실행되고 한 번만 인스턴스화 됩니다. 즉, UILabel 뷰의 생성시점을 늦출 수 있습니다. </p>
</li>
</ul>
<h3 id="참고한-자료">참고한 자료</h3>
<ol>
<li><a href="https://theswiftdev.com/lazy-initialization-in-swift/">Lazy initialization in Swift</a></li>
<li><a href="https://stackoverflow.com/questions/47367454/swift-lazy-var-vs-let-when-creating-views-programmatically-saving-memory">Swift - Lazy Var vs. Let when creating views programmatically (saving memory)</a></li>
<li><a href="https://baked-corn.tistory.com/45">[Swift] lazy Variables</a></li>
<li>스위프트 프로그래밍 3판</li>
</ol>
<blockquote>
<p> <strong>궁금한 점, 틀린 내용, 오타 지적, 오역 지적 등 피드백 환영합니다! 댓글로 남겨주세요!</strong> 
😊 🙏 </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[세트(Set)으로 배열(Array)에서 중복값 제거하기]]></title>
            <link>https://velog.io/@dev-lena/%EC%84%B8%ED%8A%B8Set%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%97%B4Array%EC%97%90%EC%84%9C-%EC%A4%91%EB%B3%B5%EA%B0%92-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@dev-lena/%EC%84%B8%ED%8A%B8Set%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%97%B4Array%EC%97%90%EC%84%9C-%EC%A4%91%EB%B3%B5%EA%B0%92-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 10 Mar 2020 14:01:55 GMT</pubDate>
            <description><![CDATA[<p>📢기억하려고 기록해놓는 글</p>
<h2 id="사전지식">사전지식</h2>
<h3 id="세트set이란">세트(Set)이란?</h3>
<ul>
<li><strong>같은 타입의 데이터</strong>들의 묶음</li>
<li><strong>순서 없음</strong></li>
<li>컬렉션 타입</li>
<li>세트 내의 값은 모두 <strong>유일한 값</strong></li>
<li>세트의 요소는 해시 가능한 값</li>
<li><strong>축약형 표현이 없고</strong> Set&lt;타입&gt;() 과 같이 Set임을 명시해야함</li>
<li>추가 및 삭제 : <strong>insert(<em>:), remove(</em>:)</strong> -&gt; Set를 반환</li>
<li><strong>교집합 set.intersection(컬렉션) / 여집합 set.symmetricDifference(컬렉션) / 합집합 set.union(컬렉션) / 차집합 set.subtracting(컬렉션)</strong><br>📢(여기서 컬렉션은 배열, 세트, 딕셔너리)</li>
</ul>
<h3 id="array배열과-차이점은">Array(배열)과 차이점은?</h3>
<p>가장 큰 차이점은 배열은 세트와 달리 인덱스가 존재합니다. 그리고 중복값을 허용합니다.</p>
<h2 id="set으로-array배열에서-중복값-제거하기">Set으로 Array(배열)에서 중복값 제거하기</h2>
<p>배열에 있는 중복값을 제거하고 싶을 때</p>
<pre><code class="language-swift">// Set 없이 반복문으로 중복값 제거하기 
func removeDuplication(in array: [Int]) -&gt; [Int]{
        var duplicationRemovedArray = array
        for index in 0 ... duplicationRemovedArray.count-1 {
            if index + 1 &lt;= duplicationRemovedArray.count-1 {
                if duplicationRemovedArray[index] == duplicationRemovedArray[index+1] {
                    duplicationRemovedArray.remove(at: index)
                }
            }
        }
        return duplicationRemovedArray
   }

// Set 으로 중복값 제거하기
func removeDuplication(in array: [Int]) -&gt; [Int]{
    let set = Set(array)
    let duplicationRemovedArray = Array(set)
    return duplicationRemovedArray
}</code></pre>
<p>중복값을 담고있는 array 배열을 <code>Set</code>으로 변환해주면 중복된 값들을 제거한 <code>Set</code>을 반환합니다. 중복값이 제거된 set를 다시 <code>Array</code> array로 변환하면 중복값이 제거된 배열이 됩니다.</p>
<blockquote>
<p> <strong>궁금한 점, 틀린 내용, 오타 지적, 오역 지적 등 피드백 환영합니다! 댓글로 남겨주세요!</strong> 
😊 🙏 </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.09]]></title>
            <link>https://velog.io/@dev-lena/TIL-2020.03.09</link>
            <guid>https://velog.io/@dev-lena/TIL-2020.03.09</guid>
            <pubDate>Mon, 09 Mar 2020 16:43:47 GMT</pubDate>
            <description><![CDATA[<h3 id="오늘-한-일">오늘 한 일</h3>
<ol>
<li>Collection View에 대해서 야곰의 수업을 들었다. </li>
<li>ViewController에 있던 SegmentedControl 부분을 클래스를 만들어서 따로 분리했는데 화면에 나타나지 않았다. 시뮬레이터를 실행한 후 뷰 계층을 봤을 때는 뷰가 생성이 되서 올바른 계층에 들어가있었지만 시뮬레이터 화면에서는 보이지 않았다. 그래서 오늘은 같이 공부하는 동료 덕분에 이 부분을 해결했다. 
Custom View 클래스를 만들 때 UIView에서 필수로 구현해야하는 init(frame:), init(coder:)에 대해서 더 이해하고 전체적으로 수정했다. 
SegmentedControl 클래스 코드를 전반적으로 수정했는데, view와 viewController를 분리했을 때 delegate를 이용해서 어떻게 할 수 있는지 적용해보려고 시도했다. 
코드를 수정하는 과정에서 lazy closure나 convenience init, Set 등 필요한 개념을 추가적으로 학습했다.<ol start="3">
<li>guard let과 if let 차이점에 대한 블로그 글을 올렸다.</li>
</ol>
</li>
</ol>
<h3 id="느낀점">느낀점</h3>
<ul>
<li>수업에서 각자 하나의 객체를 맡아서 사용자가 앱을 켰을 때 부터 어떤 행동을 할 때 까지의 과정을 알아보고 설명해보는 과정이 collection view를 이해하는데 도움이 된 것 같다. </li>
<li>수업이 끝난 후 수업 내용에 대해서 내가 이해한대로 마인드맵을 그려봤는데, 저번에도 이렇게 해봤지만 이렇게 리마인드하면서 내식대로 표현해보는게 기억에 오래 남는 것 같다. 다음에도 해야지 :)</li>
<li>또 수업이 끝나고 이해가 덜 되거나 안되는 부분을 같이 수업을 들었던 동료분들과 얘기하면서 모르는 것도 해소하고 배운 내용도 질문하고 말하면서 정리해볼 수 있어서 유익했다. 앞으로도 종종 이렇게 하면 좋을 것 같다.</li>
<li>습관적으로 어떤 걸 공부할 때, 개념이나 이론 위주로 접근하는 것 같다. 개념적 이해를 하고 난 다음에 코드적으로도 접근하는 연습은 의식적으로 꾸준히 더 해야겠다. </li>
<li>매일 꾸준히 하는 멋진 분들이 계시는데 이 점은 보고 꼭 배워야겠다.<h3 id="내일-할-일">내일 할 일</h3>
<ol>
<li>포커게임 설계 다시 하기. 승자 찾기를 새로운 클래스를 만들어서 하지 말고, 기존에 있던 클래스를 활용하기.</li>
<li>다시 짠 설계를 가지고 코드 수정하기.</li>
<li>승자의 라벨 옆에 우승뱃지 이미지뷰가 보이게 하기. </li>
<li>Collection View 수업 내용 위주로 정리해서 블로그 글올리기.</li>
<li>오늘 하려고 했던 lazy property와 custom view에 대한 내용 정리하기.</li>
</ol>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[guard let과 if let의 차이점]]></title>
            <link>https://velog.io/@dev-lena/guard-let%EA%B3%BC-if-let%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</link>
            <guid>https://velog.io/@dev-lena/guard-let%EA%B3%BC-if-let%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</guid>
            <pubDate>Mon, 09 Mar 2020 13:55:06 GMT</pubDate>
            <description><![CDATA[<p>📢기억하려고 기록해놓는 글</p>
<h3 id="비교-코드">비교 코드</h3>
<pre><code class="language-swift">//if let
func printName(){
  var value:String?
  value = &quot;Lena&quot;
  print(value) // Optional(&quot;Lena&quot;)
  if let name = value {
    print(name) // &quot;Lena&quot;
  } 
  //if문 안에서만 name 변수를 사용 가능.
}

//guard let
func printName(){
  var value:String?
  value = &quot;Lena&quot;
  print(value) // Optional(&quot;Lena&quot;)
  guard let name = value else { return }
  print(name) // &quot;Lena&quot;
  //name변수는 메소드 내에서 지역상수처럼 사용 가능.
}
</code></pre>
<h3 id="guard-let">guard let</h3>
<p><code>guard</code> 뒤에 따라붙는 코드의 실행 결과가 true일 때 코드가 계속 실행됩니다. 
if 구문과는 다르게 <code>guard</code> 구문은 항상 <code>else</code> 구문이 뒤에 따라와야 합니다. 
만약 <strong>guard 뒤 따라오는 <code>Bool</code></strong> 값이 false라면 else의 블록 내부 코드를 실행하게 됩니다.
이 내부 코드에는 자신보다 <strong>상위 코드 블록을 종료하는 코드</strong>가 반드시 들어가게 됩니다. 
코드 블록 종료시 <code>return, break, continue, throw</code> 등 제어문 전환 명령을 사용합니다.</p>
<p>Bool타입의 값으로 guard문 동작시킬 수 있지만 <strong><code>옵셔널 바인딩</code></strong> 역할도 가능합니다. 
이렇게 사용시 <code>guard로 옵셔널 바인딩 된 상수</code>를 guard 구문 실행 코드 아래부터 <strong><code>함수 내부의 지역상수</code>처럼 사용 가능합니다.</strong></p>
<p>guard let으로 할 경우 &#39;,&#39;(쉼표)로 <code>추가조건</code>을 나열할 수 있고 조건은 <code>Bool 타입</code> 값이어야 합니다. &#39;,&#39;로 나열했을 때 <code>AND 논리연산자</code>와 같은 결과이고, &#39;,&#39;를 &#39;&amp;&amp;&#39; 로 치환 가능</p>
<h3 id="장점"><strong>장점</strong></h3>
<p>guard 구문 사용시 if 코드를 훨씬 간결하고 읽기 좋게 구성 가능합니다. 
예외사항만을 처리하고 싶다면 guard 구문을 사용하는 것이 훨씬 간편합니다.</p>
<h3 id="단"><strong>단,</strong></h3>
<p><code>guard</code>는 return,break,continue,throw 등의 <code>제어문 전환 명령어</code>를 쓸 수 없는 상황이라면 사용이 불가능합니다. 함수나 메서드, 반복문 등 <code>특정 블록 내부</code>에 위치하지 않는다면 사용이 제한됩니다.</p>
<h3 id="if-let">if let</h3>
<p>if let로 옵셔널 바인딩 된 상수는 그 블럭 안에서만 변수가 사용 가능합니다</p>
<h3 id="참고한-자료">참고한 자료</h3>
<ul>
<li>스위프트 프로그래밍 3판</li>
</ul>
<blockquote>
<p> <strong>궁금한 점, 틀린 내용, 오타 지적, 오역 지적 등 피드백 환영합니다! 댓글로 남겨주세요!</strong> 
😊 🙏 </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] AppDelegate와 SceneDelegate]]></title>
            <link>https://velog.io/@dev-lena/iOS-AppDelegate%EC%99%80-SceneDelegate</link>
            <guid>https://velog.io/@dev-lena/iOS-AppDelegate%EC%99%80-SceneDelegate</guid>
            <pubDate>Thu, 05 Mar 2020 18:38:32 GMT</pubDate>
            <description><![CDATA[<h1 id="블로그-이전했습니다">**블로그 이전했습니다!</h1>
<h1 id="이-글은-이곳에서-확인할-수-있습니다">이 글은 <a href="https://lena-chamna.netlify.app/post/appdelegate_and_scenedelegate/">이곳</a>에서 확인할 수 있습니다!**</h1>
<p>← 오늘 주제를 요약하는 사진</p>
<p><img src="https://images.velog.io/images/dev-lena/post/148cbeeb-9db2-42ff-a2c9-2bd8a10bc839/image.png" alt=""></p>
<p>Xcode에서 프로젝트를 생성하면 자동으로 추가되어있는 swift 파일 중에 <code>AppDelegate.swift</code>와 <code>SceneDelegate.swift</code> 파일이 있어요!
오늘은 이 두 swift 파일에 있는 AppDelegate클래스와 SceneDelegate클래스에 대해서 알아보려고 합니다 😁 </p>
<h2 id="appdelegate와-scenedelegate">AppDelegate와 SceneDelegate</h2>
<h3 id="사전-지식-용어">사전 지식 (용어)</h3>
<p>1.<code>객체 (Object)</code>: 클래스의 인스턴스.
2.<code>인스턴스 (Instance)</code>: 클래스(즉, 객체)나 구조체, 열거형의 구체적인/특정한 발생(A specific occurrence)
3.<code>클래스 (Class)</code>: 특정한 타입의 객체에 공통되는 동작과 속성을 묘사한 코드 조각으로 본질적으로 객체의 청사진을 제공. 
(Start Developing iOS Apps (Swift)- iOS and Swift Terminology Glossary 참고)</p>
<h3 id="ios13부터-바뀐-점">iOS13부터 바뀐 점</h3>
<ul>
<li>바뀌기 이전(~iOS12)
<img src="https://i.imgur.com/CDwg5Ny.png" alt=""></li>
<li>바뀐 후 (iOS13)
<img src="https://i.imgur.com/D4VfgIv.png" alt="">
(사진은 wwdc 2019 영상에서 가져왔습니다)</li>
</ul>
<p>*<em>1. iOS12까지는 대부분 하나의 앱에 하나의 <code>window</code>였지만 iOS 13부터는 window의 개념이 <code>scene</code>으로 대체되고 아래의 사진처럼 하나의 앱에서 여러개의 scene을 가질 수 있습니다. *</em>
<img src="https://i.imgur.com/sK5PvQo.jpg" alt=""></p>
<p><strong>2. AppDelegate의 역할 중 UI의 상태를 알 수 있는 UILifeCycle에 대한 부분을 <code>SceneDelegate</code>가 하게 됐습니다.</strong>
<img src="https://i.imgur.com/tGlsHON.png" alt=""></p>
<p><strong>3. 그리고 AppDelegate에 <code>Session Lifecycle</code>에 대한 역할이 추가됐습니다.</strong>
<img src="https://i.imgur.com/enmQrnB.png" alt=""></p>
<p>Scene Session이 생성되거나 삭제될 때 AppDelegate에 알리는 두 메소드가 추가됐는데요.
Scene Session은 앱에서 생성한 모든 scene의 정보를 관리합니다.</p>
<p><strong>iOS 13부터는 window의 개념이 <code>scene</code>으로 대체됐다고 하는데요! 그럼 Scene은 뭘까요?</strong> </p>
<h3 id="scene">Scene?</h3>
<blockquote>
<p>UIKit는 UIWindowScene 객체를 사용하는 앱 UI의 각 인스턴스를 관리합니다. <strong>Scene에는 UI의 하나의 인스턴스를 나타내는 windows와 view controllers가 들어있습니다.</strong> 또한 각 <strong>scene에 해당하는 UIWindowSceneDelegate 객체</strong>를 가지고 있고, 이 객체는 <strong>UIKit와 앱 간의 상호 작용을 조정</strong>하는 데 사용합니다. Scene들은 같은 메모리와 앱 프로세스 공간을 공유하면서 서로 동시에 실행됩니다. <strong>결과적으로 하나의 앱은 여러 scene과 scene delegate 객체를 동시에 활성화</strong>할 수 있습니다.
(Scenes - Apple Developer Document 참고)</p>
</blockquote>
<p>** UI의 상태를 알 수 있는 UILifeCycle에 대한 역할을 <code>SceneDelegate</code>가 하게 됐죠! 역할이 분리된 대신 <code>AppDelegate</code>에서 Scene Session을 통해서 scene에 대한 정보를 업데이트 받는데요! 그럼 Scene Session은 뭘까요??**</p>
<h3 id="scene-session">Scene Session?</h3>
<blockquote>
<p><strong>UISceneSession 객체</strong>는 scene의 고유의 런타임 인스턴스를 관리합니다. 사용자가 앱에 새로운 scene을 추가하거나 프로그래밍적으로 scene을 요청하면, 시스탬은 그 scene을 추적하는 session 객체를 생성합니다. <strong>그 session에는 고유한 식별자와 scene의 구성 세부사항(configuration details)가 들어있습니다.</strong> UIKit는 session 정보를 그 scene 자체의 생애(life time)동안 유지하고 app switcher에서 사용자가 그 scene을 클로징하는 것에 대응하여 그 session을 파괴합니다. session 객체는 직접 생성하지않고 UIKit가 앱의 사용자 인터페이스에 대응하여 생성합니다. 또한 위 3번에서 소개한 두 메소드를 통해서 UIKit에 새로운 scene과 session을 프로그래밍적 방식으로 생성할 수 있습니다.
(UISceneSession - Apple Developer Document 참고)</p>
</blockquote>
<p><strong>그럼 SceneDelegate가 추가된 iOS13에서 AppDelegate는 어떤 일을 할까요??</strong></p>
<h3 id="ios13부터-appdelegate가-하는-일">iOS13부터 AppDelegate가 하는 일?</h3>
<blockquote>
<p>이전에는 앱이 foreground에 들어가거나 background로 이동할 때 앱의 상태를 업데이트하는 등의 앱의 주요 생명 주기 이벤트를 관리했었지만 더이상 하지 않습니다.
현재 하는 일은
<strong>1. 앱의 가장 중요한 데이터 구조를 초기화하는 것
2. 앱의 scene을 환경설정(Configuration)하는 것
3. 앱 밖에서 발생한 알림(배터리 부족, 다운로드 완료 등)에 대응하는 것
4. 특정한 scenes, views, view controllers에 한정되지 않고 앱 자체를 타겟하는 이벤트에 대응하는 것. 
5. 애플 푸쉬 알림 서브스와 같이 실행시 요구되는 모든 서비스를 등록하는것.
입니다.</strong>
(UIApplicationDelegate - Apple Developer Document 참고)</p>
</blockquote>
<p><img src="https://i.imgur.com/NYKSNdl.png" alt="">
AppDelegate 클래스는 새로운 프로젝트를 생성할 때마다 자동으로 생성됩니다. 저는 이 AppDelegate 클래스가 채택하고 있는 UIApplicationDelegate에 들어가 봤는데요. 위 사진과 같은 메소드들이 있었습니다. 
보통의 경우, 앱을 초기화하고 앱레벨의 이벤트에 반응하기 위해서는 Xcode가 제공하는 이 클래스를 사용해야 합니다. UIApplicationDelegate 프로토콜은 앱을 설정하고, 앱의 상태 변화에 대응하며, 다른 앱 레벨의 이벤트를 처리하는 데 사용하는 여러 가지 메소드를 정의합니다.</p>
<h3 id="deployment-target이-ios-13-미만인-상황에서는">Deployment Target이 iOS 13 미만인 상황에서는?</h3>
<p><strong>Deployment Target이 iOS 13 미만인 상황에서도 UIScene과 UISceneDelegate를 사용할 수 있을까요? 만약 앱이 iOS 13 미만의 버전도 지원해야 한다면 어떻게 해야할까요?</strong></p>
<p>iOS 12 이하는 하나의 앱에 하나의 window를 가지고 있기 때문에(즉, multi window를 사용하지 않기 때문에) iOS 13에서 추가된 부분을 삭제하고 이전 버전(~iOS12)과 설정을 똑같이 바꿔주면 이전 방식대로과 동일하게 할 수 있습니다.
방법은 Xcode를 새로 열고</p>
<blockquote>
<ol>
<li>iOS13에서 새로 생긴 <strong><code>SceneDelegate.swift</code></strong> 파일 삭제</li>
<li>iOS13에서 <code>AppDelegate</code>에 추가된  <strong><code>UISceneSession</code>과 관련된 두 메소드</strong> 삭제
<img src="https://images.velog.io/images/dev-lena/post/5ded9716-3ec0-49ac-98e0-57fbb34eabc6/image.png" alt=""></li>
<li>iOS13에서 <code>SceneDelegate</code>로 옮겨진 <strong><code>window</code> 프로퍼티</strong>를 AppDelegate로 다시 옮기기</li>
</ol>
</blockquote>
<pre><code class="language-swift">    var window: UIWindow?</code></pre>
<ol start="4">
<li><strong><code>info.plist</code></strong>에서 Scene과 관련된 Manifest인 <code>Application Scene Manifest</code>삭제</li>
</ol>
<p>직접 해봤는데 Build Success가 뜨네요! iOS13 미만인 경우 이렇게 하면 될 것 같습니다.</p>
<h3 id="참고한-자료">참고한 자료</h3>
<ol>
<li><a href="https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/BuildABasicUI.html#//apple_ref/doc/uid/TP40015214-CH5-SW1">DevelopiOSAppsSwift - BuildABasicUI</a></li>
<li><a href="https://zeddios.tistory.com/218">iOS ) AppDelegate.swift의 역할</a> - zedd님 블로그</li>
<li><a href="https://developer.apple.com/videos/play/wwdc2019/258/">Architecting Your App for Multiple Windows</a> - wwdc 2019</li>
<li><a href="https://zeddios.tistory.com/811">SceneDelegate (1) - Architecting Your App for Multiple Windows</a> - zedd님 블로그</li>
<li><a href="https://usinuniverse.bitbucket.io/blog/scenedelegatepart1.html">SceneDelegate와 AppDelegate part 1 [번역]</a></li>
<li><a href="https://developer.apple.com/documentation/uikit/app_and_environment/scenes">Scenes - Apple Developer Document</a></li>
<li><a href="https://developer.apple.com/documentation/uikit/uiscenesession">UIscenesession - Apple Developer Document</a></li>
<li><a href="https://developer.apple.com/documentation/uikit/uiapplicationdelegate">UIApplicationDelegate - Apple Developer Document</a></li>
</ol>
<blockquote>
<p>** 도움 주신 분**
야곰 
<strong>감사합니다🙏</strong></p>
</blockquote>
<blockquote>
<p>애플 공식문서를 번역해봤는데 오역이 있을 수 있습니다 😢 
<strong>궁금한 점, 틀린 내용, 오타 지적, 오역 지적, 칭찬, 격려 등 모두 환영합니다! 댓글로 남겨주세요!</strong> 
읽어주셔서 감사합니다! 😊 🙏 </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I Learned 2020.03.05]]></title>
            <link>https://velog.io/@dev-lena/Today-I-Learned-2020.03.05</link>
            <guid>https://velog.io/@dev-lena/Today-I-Learned-2020.03.05</guid>
            <pubDate>Thu, 05 Mar 2020 17:38:25 GMT</pubDate>
            <description><![CDATA[<h3 id="오늘-한-일">오늘 한 일</h3>
<ol>
<li>어제 오늘 PokerGame에서 승자를 가려내는 코드를 짜기 위해 설계하고 코드로 쳐봤지만 실패했다.</li>
<li>Set, Dictionary, Array 중 어디에 담을지, 내가 필요한 기능을 기원하는지 알아봤다. </li>
<li>야곰이 추천해준 Start Developing iOS Apps (Swift)에서 FoodTracker를 만들고있다. </li>
</ol>
<p><strong>[Start Developing iOS Apps (Swift) - Building the UI]</strong>
3-1. Build a Basic UI(끝)
3-2. Connect the UI to Code(끝)
3-3. Work with View Controllers(하는 중)
(<a href="https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/BuildABasicUI.html#//apple_ref/doc/uid/TP40015214-CH5-SW1">https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/BuildABasicUI.html#//apple_ref/doc/uid/TP40015214-CH5-SW1</a>)</p>
<h3 id="새롭게-알게-된-것">새롭게 알게 된 것</h3>
<ul>
<li>용어</li>
</ul>
<p>1.<code>subclass</code>: 
A class that’s a child of another class (known as its superclass).
2. <code>superclass</code>:
A class that’s a parent of another class (known as its subclass).
3. <code>data model</code>:
The representation or structure of data within an app.
4. <code>content view</code>:
A view object that’s located at the top of a view hierarchy, serving as a container for the subviews in its hierarchy.
5. <code>data model</code>:
The representation or structure of data within an app.</p>
<ul>
<li><p>StoryBoard와 Code 연결 - 방법, 메모리 올라가는 시점</p>
</li>
<li><p>IBOutlet과 IBAction</p>
</li>
<li><p>IBOutlet이 weak Reference인 이유
<img src="https://i.imgur.com/VlKklUX.png" alt=""></p>
</li>
<li><p>Attributes inspector에서 textfield에서 사용자가 text field에 text를 타이핑하지 않으면 Done 키를 누르지 못하도록 하는 방법
<img src="https://i.imgur.com/4d7zl4g.png" alt=""></p>
</li>
</ul>
<h3 id="느낀점">느낀점</h3>
<ol>
<li>설계를 했다고 확인없이 한번에 코드를 치지 말자.</li>
<li>너무 한번에 끝내려고 하지 말자. 보고 또 보고, 해보고 또 실패하고 또 해보고 하자.</li>
<li>내가 이해한 걸 나의 말로 정리할 필요가 있는 것 같다. 앞으로 TIL 말고도 블로그에 공부하고 이해한 내용들을 포스팅해보려고 한다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.03]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.03</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.03</guid>
            <pubDate>Tue, 03 Mar 2020 19:09:13 GMT</pubDate>
            <description><![CDATA[<p>오늘은 야곰이 추천해준 &#39;Start Developing iOS Apps (Swift)&#39;을 직접해보면서 문서에 나온 내용을 공부하기 시작했습니다:) </p>
<p>야곰닷넷에도 올렸어요!
(<a href="https://yagom.net/forums/topic/start-developing-ios-apps-swift-day-1/">https://yagom.net/forums/topic/start-developing-ios-apps-swift-day-1/</a>)</p>
<h2 id="새로-알게된-내용들">새로 알게된 내용들</h2>
<h2 id="appdelegate와-scenedelegate">AppDelegate와 SceneDelegate</h2>
<p>블로그 포스팅으로 업로드 했습니다!
<a href="https://velog.io/@dev-lena/iOS-AppDelegate%EC%99%80-SceneDelegate">https://velog.io/@dev-lena/iOS-AppDelegate와-SceneDelegate</a></p>
<h3 id="느낀점">느낀점</h3>
<p>앱이 어떻게 구동되는지에 대한 원리를 언제 한번 봐야지 봐야지 했는데 오늘 좀 알게 되서 좋았다. 그런데 AppDelegate와 SceneDelegate를 보느라 Start Developing iOS Apps (Swift)에서 FoodTracker 앱을 만들어보는 진도는 나가지 못했다. 원래 목표가 간단한 하나의 앱을 처음부터 끝까지 관련 내용을 공부하면서 만들어보는 거였는데, 이런 방식대로라면 일주일동안 완성하지 못할 것 같다. 깊이보는 것도 좋지만 내일은 알고 간략한 핵심만 정리하고 넘어가도록 해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.03.01]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.01</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.03.01</guid>
            <pubDate>Sun, 01 Mar 2020 16:52:38 GMT</pubDate>
            <description><![CDATA[<p>오늘은 메모리 관점에서 클로저에 대해 더 이전보다 조금 더 알아봤다.
공부한 순서와 키워드를 기록하자면,
<code>Closure</code>(Closure,Trailing Closure,Escaping Closure) -&gt; <code>메모리 기본</code>(메모리 공간, stack과 heap) -&gt; <code>Reference Type</code>과 <code>Value Type</code> -&gt; <code>ARC</code>(Reference Count, Strong Reference, Weak Reference, Unowned Reference) -&gt; <code>Strong Reference Cycle</code> -&gt; <code>Capture List</code></p>
<p>아직 다른 부분은 추가적인 학습이 필요한 것 같아서 Closure에 Capture에 대해서만 기록해보려고 한다.
이 내용은 야곰이 오픈한 홈페이지에도 올렸다! (<a href="https://yagom.net/forums/topic/closure%EC%9D%98-capture/">https://yagom.net/forums/topic/closure의-capture/</a>)</p>
<h1 id="closure의-capture">Closure의 Capture</h1>
<h3 id="1-클로저는">1. 클로저는</h3>
<pre><code class="language-swift">func makelncrementer(forlncrement amount: Int) -) (() -) Int) { 
var runningTotal =0
func incrementer() -&gt; Int {
runningTotal += amount return runningTotal
  }
return incrementer
}

let incrementByTwo: (() -&gt;Int) =makelncrementer(forlncrement: 2) 
let sameWithlncrementByTwo: (() -&gt; Int ) = incrementByTwo
let first: Int =incrementByTwo() // 2 
let second: Int =sameWithlncrementByTwo() // 4</code></pre>
<p>클로저는 자신이 정의된 위치의 주변 문맥을 통해 상수나 변수를 획득(capture)할 수 있습니다. 값 획득(Capture)을 통해 클로저는 주변에 정의한 상수나 변수가 더 이상 존재하지 않더라도 해당 상수나 변수의 값을 자신 내부에서 참조하거나 수정할 수 있습니다. </p>
<p>상수에 클로저를 할당한다는 것은 클로저의 값을 할당하는 것이 아니라 해당 클로저의 참조를 할당하는 것입니다. </p>
<h3 id="2-클로저는-클래스와-마찬가지로-reference-type">2. 클로저는 클래스와 마찬가지로 Reference Type</h3>
<p>값 전달할 때 마다 stack에 주소가 복사됩니다.
참조 방식에서 &#39;참조&#39;는 stack에 저장되어있는 주소를 의미합니다.</p>
<h3 id="3-클로저의-캡쳐와-캡쳐리스트를-통한-캡쳐">3. 클로저의 캡쳐와 캡쳐리스트를 통한 캡쳐</h3>
<pre><code class="language-swift">var firstOne = 0
var secondOne = 0
let closure = {print (firstOne,secondOne)}
firstOne = 1
secondOne = 2
closure() // 결과 : 1,2
</code></pre>
<p>closure 상수에 저장된 클로저는 firstOne, secondOne 두 상수를 캡쳐합니다.
클로저가 값을 캡쳐할 땐 복사본이 아니라 참조(값의 주소, reference)가 전달합니다. 두 변수를 변경하고 클로저를 호출하면 클로저가 생성된 시점에 두 변수에 저장되어있던 값이 아니라 변경된 현재 값이 출력됩니다.</p>
<pre><code class="language-swift">var firstOne = 0
var secondOne = 0
let closure = { [firstOne] in print (firstOne,secondOne)}
firstOne = 1
secondOne = 2
closure() // 결과 : 0,2
</code></pre>
<p>하지만 캡쳐 리스트(Capture List)를 통해 firstOne을 캡쳐하면 이전과 달리 참조가 전달되지 않습니다. 왜냐하면 firstOne에 저장되어있는 값과 동일한 값을 가진 상수 복사본이 전달되기 때문입니다. 그래서 클로저를 선언한 후(3번째 라인)에 fisrtOne 값을 변경하더라도, 변경되지 않은 클로저에서 캡쳐된 firstOne의 값이 출력됩니다. 즉, 캡쳐 대상으로 지정한 firstOne은 값이 복사되서 전달됐으므로 0이 출력됩니다.</p>
<h3 id="4-클로저-내-self">4. 클로저 내 self</h3>
<pre><code class="language-swift">class Person{
var name = &quot;Lena&quot;
var job = &quot;developer&quot;
lazy var nameTag: () -&gt; String = {
return self.name + self.job
  }
}</code></pre>
<p>클로저는 self 키워드를 통해 인스턴스 속성에 접근합니다. self는 인스턴스 자체를 나타내는 속성으로, 클로저에서 사용하면 self가 캡쳐됩니다. 위 예제 코드(3번)에서는 self가 Person이라는 클래스이고 이 클래스 인스턴스를 캡쳐합니다. 그리고 이 클래스의 속성인 namer과 job에 접근합니다. 클로저는 자신의 실행이 종료될 때 까지 self가 메모리에 유지되도록 강한참조로 캡쳐합니다.이 클로저는 인스턴스 속성(Person이라는 클래스의 프로퍼티)에 저장됩니다. 
(3번 예제 코드는 클로저의 강한참조 순환문제가 일어나는 코드입니다. 이 문제는 Capture List로 해결할 수 있습니다.)</p>
<h3 id="참고한-자료">참고한 자료</h3>
<p>&#39;스위프트 프로그래밍 3판&#39; (지은이: 야곰)
&#39;Closures — The Swift Programming Language (Swift 5.2)&#39;
<a href="https://docs.swift.org/swift-book/LanguageGuide/Closures.html">https://docs.swift.org/swift-book/LanguageGuide/Closures.html</a></p>
<p><strong>오늘 하루 소감</strong>
쉬는 동안 해야할 일을 적어봤는데 주어진 시간에 비해서 해야할 목록이 빠듯했다.
우선순위가 필요한 것 같다. 적어보지 않고 생각만했을 때는 쉬면서 충분히 할 수있을거라고 생각했는데, 적어보니 빠듯한 정도가 아니라 모자를 것 같다. 꼭 달성할 목표를 정해놓고 집중해야할 것 같다!
그리고 야곰 홈페이지에 글을 처음 써봤다. 내가 이해한 내용이 맞는지 올려보고 교정도 받을 수 있어서 좋은 기회인것 같다! 하지만 잘 모르는 상태에서 글을 쓰는 것 같아서 조금 부담스럽기는 하다. 하지만 표현을 해야 내가 아는 것과 모르는 것을 명확하게 알게 되니까 열심히하자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.02.26]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.26</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.26</guid>
            <pubDate>Wed, 26 Feb 2020 16:53:26 GMT</pubDate>
            <description><![CDATA[<h1 id="지난-며칠동안-한-일">지난 며칠동안 한 일</h1>
<ol>
<li><strong>클로저</strong> 를 인자로 넘기는 방법을 사용해 클래스의 private 프로퍼티에 접근하는 방법을 사용해봤다. 클래스의 프로퍼티를 외부에서 변경하거나 직접 부르는 일이 없도록 했다.</li>
<li><strong>클래스</strong>를 통해 만든 기능을 <strong>ViewController</strong>와 연결해서 써봤다.</li>
<li><strong>shake gesture</strong>를 써봤다</li>
<li><strong>StackView</strong>를 사용하고 화면을 구성해봤다. (stackView 안에 stackView 안에 stackView를 넣어봤다)</li>
<li><strong>enum</strong>의 rawValue를 외부에서 직접적으로 부르거나 변경하지 않고 구현해봤다(클로저 사용)</li>
<li>Card 클래스의 description에 맞는 이미지 이름을 갖고 있는 UIImage를 매칭해 view로 생성했다.</li>
<li><strong>segmented Control</strong>을 사용했다. 선택에 따라 동작한다.</li>
<li>동료들과 진행 상황과 오늘 할 일에 대해서 <strong>스크럼</strong>을 했다.</li>
<li><strong>ARC(Auto Reference Counting)</strong>, <strong>순환참조</strong> 문제, <strong>강한참조</strong> strong reference, <strong>약한참조</strong> weak reference, <strong>미소유참조</strong>unowned reference에 대한 강의를 들었다.</li>
<li><strong>KVO</strong>(Key Value Object), <strong>Observer</strong>, Observer Pattern에 대한 강의를 들었다.</li>
<li><strong>클래스, 객체, 인스턴스</strong>에 대해서 다시 한번 생각해보고 학습했다. (메모리적인 부분에 대해서 더 학습하긴 했지만 간단하게 결론을 아직 확실하게 내지는 못했다.)
<a href="https://developer.apple.com/videos/play/wwdc2016/416/">Understanding Swift Performance - WWDC 2016 - Videos - Apple Developer</a></li>
<li><strong>Codable, Archiving</strong>에 대한 수업을 들었다. 수업을 듣고 마인드맵과 그림으로 내 방식대로 정리해봤다.</li>
<li>마스터(jk)와 <strong>면담</strong>을 했다.</li>
</ol>
<h1 id="새롭게-알게-된-것">새롭게 알게 된 것</h1>
<p><img src="https://images.velog.io/images/dev-lena/post/3292f52b-8981-4c12-a839-42487d4e25d3/image.png" alt="">!
아랫쪽 빨간 박스에서 실행되는 메소드들의 stack을 확인할 수 있다.
왼쪽 빨간 박스에서 view들의 계층을 확인할 수 있다.
콘솔에 &quot;PO&quot;를 활용해서 디버깅할 수 있다.
--&gt; po: print object, 객체의 description 메서드 호출 결과 출력
<a href="https://ohgyun.com/635">https://ohgyun.com/635</a> 참고</p>
<p>클래스에 private 프로퍼티(A)를 외부에서 사용하고 싶을 때 그 프로퍼티(A)가 있는 곳에 클로저를 인자로 받아오는 메소드를 만드는 방법이 있다. 이 메소드를 통해서 private 프로퍼티(A)를 외부에서 사용할 수 있다. (단, 호출은 할 수 있지만 변형은 제한된다고 알고있다.)</p>
<pre><code class="language-swift">    class Players {
    private players = [Player]()
    func showEachPlayer(behavior: (Player) -&gt; ()) {
        players.forEach {
            behavior($0)
        }
    }
    }</code></pre>
<h1 id="기억할-것">기억할 것</h1>
<blockquote>
<ol>
<li>모르는 건 그 순간에 이해하려고 노력하고 말해보자</li>
<li>질문하자. 질문을 할 때는 횡설수설하지 말고 질문을 정리하고 명확하게 하자.</li>
<li>개념적인 걸 알았으면 practical 하게 코드로 녹여보자</li>
<li>집중이 잘 될 때 하는 일과 아닐 때 하는 일을 나눠야 한다. 긴 호흡의 집중과 짧은 호흡의 집중을 구분할 수 있어야 한다. 학습의 덩어리가 큰지 작은지 아는 게 중요하다. </li>
<li>너무 디테일하게 하지 말고 핵심만 요약해 보자. 다른 사람의 자료나 지식, 생각이나 접근을 내 방식대로 소화하거나 표현/정리해보고 내 식대로 다시 변형하거나 구현해보자</li>
<li>지식을 잇는걸 잘해야 학습도 잘한다. 내가 알고 있는 것 위에 쌓아 올리자.</li>
</ol>
</blockquote>
<h1 id="오늘의-시도와-결론">오늘의 시도와 결론</h1>
<p><strong>[ 실패 하나 😊 ]</strong>
<img src="https://images.velog.io/images/dev-lena/post/e49c7adf-e9a2-4d2f-b0f8-cf692f01566f/image.png" alt=""></p>
<ul>
<li><strong>시계방향으로 90도 돌리면 약간 에스컬레이터 같은 느낌이 난다. 조금 웃프지만 이거 덕분에 그 날 하루가 되게 웃겼던 것 같다. 이거 저거 실패해보면서 재밌었다.</strong></li>
</ul>
<p>의도한 것과 다르게 나타났던 부분</p>
<ol>
<li>UIImageview가 StackView에 5개만 쌓여야 하는데 10개가 쌓였다.</li>
<li>모든 UIImageview는 StackView에 들어갔지만 몇몇 UIImage는 출력되지 않았다.</li>
<li>객체마다 다 다른 값이 들어가야 할 부분에 모두 같은 값이 들어갔다.</li>
</ol>
<p>문제의 원인</p>
<ol>
<li>코드 상단에 초기화 해놓은 클래스 설정과 이 클래스와 관련있는 다른 변수들의 설정이 달랐다. 아래에 짜놓은 코드는 이 두 개를 혼합해서 쓰고 있었기 때문에 의도대로 되지 않았다.</li>
<li>UIImage(name: A.description)에서 A.description이 이미지의 이름과 매칭되도록 해줘야 하는데, 예외의 경우를 처리하지 않아서 몇 몇 UIImage만 출력이 되지 않았다.</li>
<li>같은 값을 가져와서 모든 객체에게 같은 값을 넘겨주고 있었다.</li>
</ol>
<p><strong>[ 결론 👩‍💻 ]</strong>
나는 이 문제를 3일 넘게 붙잡고 있었고, 이거 때문에 봐도 봐도 모르겠고 옆사람들에게 물어봐도 모르겠고 해서 결국 마스터에게 찾아가서 물어봤다. 차근 차근 어디가 문제인지 혹시 이게 문제는 아닌지 저게 문제가 아닌지 되짚어가는 걸 보기만 해도 배운 느낌이다.</p>
<p>일단, 문제가 있는 부분부터 차근차근 코드를 추적해서 보자. 
그리고 view에 문제가 있다면 코드만 보지말고 view 계층도 추적하면서 봐보자.</p>
<h1 id="내일-할-일">내일 할 일</h1>
<ol>
<li>closure, reference type, ARC, closure capture에 대해서 학습</li>
<li>피드백 반영 후 수정하기 </li>
<li>viewController와 view 나누기 -&gt; MVC 패턴 고민해보기</li>
<li>responder Chain 수업듣기</li>
</ol>
<h1 id="느낀점">느낀점</h1>
<p> 집중이 안될 때는 급한 일?이나 짧게 끝나는 일 부터 시작하자. &#39;아 이것만 하자&#39; 하고 한 번 시작하면 집중과 흐름이 잡히는 것 같다.
 오전 시간을 그냥 보내지 말자. 
 질문도 하면 할수록 나아지고 실패도 하면 할 수록 나아진다.
 실패하면서 배우는 건 당시에는 스트레스를 받기는 하지만 생각보다 더 재밌다.
 나중에 내가 어떤 걸 할 수 있게 될지 조금 기대된다.
 <code>seize the day</code>  - 죽은 시인의 사회</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.02.20]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.20</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.20</guid>
            <pubDate>Thu, 20 Feb 2020 16:13:43 GMT</pubDate>
            <description><![CDATA[<h2 id="새로-알게-된-키워드">새로 알게 된 키워드</h2>
<p>학습하거나 공부했다기 보다는 지난 몇 일 동안 정말로 새로 알게된 용어나 키워드들을 적어봤다.</p>
<blockquote>
<p><code>KVO(Key, Value, Object)</code> <code>observer</code> <code>observer pattern</code> <code>NSObject</code> <code>@objc dynamic var</code> <code>NotificationCenter</code> <code>ARC(Auto Referenc Counting</code> <code>deinit</code> <code>weak reference</code> <code>strong reference</code> <code>unowned reference</code> <code>순환참조</code> </p>
</blockquote>
<h2 id="오늘-기록">오늘 기록</h2>
<p>이번주는 체력도 체력이지만 내내 갈피를 못잡은 것 같아서 몇 일동안은 코드를 몇 줄 치지도, 그렇다고 어떤 주제를 가지고 제대로 공부를 하지도 않은 것 같다. </p>
<p>지금 내 상황을 표현하자면 내게 주어진 시간안에 소화할 수 있는 양보다 훨씬 더 많은 양의 음식이 지속적으로 내 입으로 들어오고 있는 것 같다. 위로 들어가 소화되기는 커녕 목구멍에서 막히는 기분이랄까. </p>
<p>그래서 요 며칠간은 생각을 해봤다. 이 문제는 내가 개발자가 되기를 희망하는 동안 멈추지 않고 놓을 수도 없는 문제일 거 같다. 혹시 들인 시간이 작았나, 주제를 잘못 선정했나, 제대로 이해하지 않고 넘어갔나...</p>
<h3 id="스스로-평가">스스로 평가</h3>
<p>일단 지난 주말부터 이번주(월-오늘 목요일) 평가하자면</p>
<ol>
<li><p>완전 모르는 문제를 직면하게 됐을 때, 뭉텅이로 생각해서 지레 겁먹고 시작하기를 꺼려했다. 아예 접근조차 하지 않으려고 했던 것 같기도 하다. 어제 오늘이 되어서야 언제까지나 외면할 수는 없다고 느꼈다. <strong>일단 문제가 뭔지 제대로 파악하는게 먼저고, 그 다음에는 문제를 작게 쪼개는 연습이 필요하다.</strong> 문제를 작게 작게 쪼개서 &#39;지금 당장 timer 45분동안 어떤 걸 해봐야겠다&#39; 까지 나오도록 하는게 좋은 것 같다.</p>
</li>
<li><p>그리고 이를 토대로 오전에는 내가 구체적으로 오늘의 목표는 무엇인지 정해봐야겠다. 사실 요 며칠동안에는 동료들과 스크럼을 하는걸 매우 꺼려했었다. 나는 진도 나간것도 없고 그렇다고 공부한 것도 없었기 때문에 매일 같이 어제 한건 없고 오늘도 뭘 해야할지 모르겠다고 말하기는 창피하기도 하고 말도 꺼내기 어려웠다. 당장 내일 부터는 <strong>최대한 구체적으로 오늘의 목표를 정해봐야겠다.</strong></p>
</li>
<li><p>구체적으로 오늘의 목표를 정하기로 마음 먹은 것은 <strong>내가 목적없는 공부를 하고 있다는 문제를 발견했기 때문</strong>이기도 하다. 공부는 끝이없을거다라고 가정하고 조사하고 알아본 것 같다. 구체적으로 예를 들자면 &#39;아 stackView는 뭐지? 어떻게 쓰지?&#39;라는 생각이 들면 구글에 일단 ios StackView를 검색하고 적당히 마음에 드는 포스트들을 새창으로 열기로 여러개 띄워놓고 찬찬히 읽어보는 정도다. 사실 내가 이전에 TIL에 공부라고 했던 건 이정도 수준인게 많았던 것 같다. 반성한다. 이건 공부라기 보다는 조사에 가깝다고 생각한다. 그렇도 본격적이지도 않고 그냥 이게 뭔지 스키밍해본 정도이다. 나는 이런 공부 방법이 목적없는 공부에서 나왔을 수도 있다는 생각이 들었다. 내가 &#39;StackView로 간단한 앱을 구현해보고 싶다.&#39;나 &#39;StackView가 뭔지 알아보고 코드적으로 구현하는 방법이나 다양한 활용법을 블로그에 소개하고 싶다&#39;와 같은 구체적인 목표가 있어야 스키밍에서 멈추는 공부가 아니라 목적있는 학습을 할 수 있는 것 같다.</p>
</li>
<li><p>소심했다. 나는 소심한 성격이야 할 때, 그 소심이라기 보다는 <strong>학습에 임하는 자세나 코드를 도전할 때 어느순간 부터 소심해진 것 같다.</strong> 무의식 중에 삽질이나 실패를 많이 하면 뒷쳐질 거라는 생각이 너무 강해서 시도도차 하고 싶지 않을 정도? <strong>모르는 건 물어보고 공부한 걸 다른 사람에게 말해보고 그러다가 설명 못하거나 정리가 되지 않은 부분이 있다면 다시 공부하고 해야겠다</strong> 적극적일 수 있는 환경에 있지만 활용하지 못하고 있는 것 같다. 부끄럽지만 다른 사람이 나를 은연중에 무시하고 있을 거라는 착각도 어느정도 한 것 같다. 자격지심이다. 열심히 해서 세계 최고가 되지 않아도 된다. 꾸준히 하자. 이번주는 이 꾸준히 하자는 목표에서 조금 멀었던 것 같다. 다시 가까워 져야겠다. <strong>내가 이해했다고 생각한걸 내뱉어보고 설명해보고 말해보고 말로 확인해보고 모르는건 질문해보자. 단, 질문도 잘해야한다. 구체적이어야 하고 명확해야하며, 올바른 접근이어야 한다. 내가 하려는 질문이 이에 부합하는지 검사하는 것 역시 공부가 필요하다.</strong></p>
</li>
<li><p>투자한 시간이 적었다. 공부할게 많은데 그걸 다 소화할 시간이 부족하다는 생각을 계속했던 것 같다. 그런데 막상 오늘 TIL을 쓰면서 느낀게, 그럼 나는 매일 몇 시간을 투자했는가 따져봤을 때 아주 적은 시간만 학습하는데 소비한 것 같다. 적어도 뭐든지 내 욕심이나 목표치만큼 해낼려면 객관적으로 시간을 투자해야하는데, 핑계만 대로 시간을 투자하지 않은 점을 반성한다. <strong>몰입하는 시간을 늘리는 것이 지금 꼭 필요한 것 같다.</strong> </p>
</li>
</ol>
<h2 id="기억하기">기억하기</h2>
<blockquote>
<ol>
<li><strong>미국의 부트 캠프는 하루에 10~12시간씩 주 6일동안 진행하면서 짧은 시간에 개발을 배운다.</strong></li>
<li><strong>몰입하는 시간을 늘리는 것이 무엇인가를 배우고 발전시키는 최고의 방법이라고 본다.</strong>
3 실무 환경을 모방한 환경을 갖춰둔다.</li>
<li><strong>자신과 비슷한 생각을 하는 다른 학생들에게 둘러싸여 있을 때 받는 동기부여가 엄청나다.</strong></li>
<li><strong>짧은 시간에 개발자로 성장하는 과정에서는 소심하거나 게을러서는 안된다.</strong>
(코딩 부트 캠프는 소심하거나 게으른 사람에 맞지 않는다)</li>
<li>개인 생활이 완전히 없다고 봐야한다. 모든 일정을 깨끗이 비워라.</li>
<li><strong>지쳐 나가 떨어질 정도로 노력해야할 것이다.</strong></li>
<li><strong>수업이 끝난 후에도 남아서 자신의 프로젝트를 작성하라. 동료들과 대화하라.</strong> 강사들과 좋은 관계를 맺고, 필요한 경우 강사들을 도와줘라.</li>
<li>과정이 끝나고 상위 90퍼센트 학생에게만 취업 기회가 주어진다면 대개 반에서 하위 10퍼센트가 되지 않기 위해 노력할 것이다. 하지만 <strong>나라면 반에서 상위 10퍼센트에 드는 걸 목표로 삼는다. 사실 아예 1등을 차지하기 위해 최선을 다할 것이다. 나라면 절대 운에 맡기지 않고 만반의 준비를 하겠다.</strong></li>
<li>최고의 학생이 되고 싶다면 유리한 고지를 점령하기 위해 할 수 있는 모든 걸 하라.</li>
<li><strong>학습 속도를 높이고 학습한 내용을 실무에 적용할 방법을 확실히 배우겠다고 마음의 준비를 단단히 하라.</strong></li>
</ol>
</blockquote>
<p>-&gt; 존 손메즈의 <code>커리어 스킬</code> 참고</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.02.14]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.14</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.14</guid>
            <pubDate>Sat, 15 Feb 2020 13:08:06 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘-한-일">오늘 한 일</h1>
<ol>
<li><p>한 주 동안 잘한점, 아쉬운점, 개선할 점, 도전할 점, 학습 키워드를 정리하고 동료들과 한 주 회고를 나눴다. </p>
</li>
<li><p>TDD 시도 : 먼저 테스트 코드 작성 (Red-Green-Refectoring)하고 코드를 구현하는 방식으로 코딩을 해봤다. </p>
</li>
<li><p>어떤 테스트 케이스를 거쳐야 그 테스트 케이스를 통과한 메소드를 신뢰할 수 있을지 고민해봤다. </p>
</li>
<li><p>요구 사항에 따라 나름대로 설계를 먼저한 후 코딩에 들어갔다.</p>
<h1 id="오늘의-시도와-결론">오늘의 시도와 결론</h1>
</li>
</ol>
<ul>
<li>TDD. <code>테스트케이스</code>를 먼저 작성하고 Red를 Green으로 바꾸면서 클래스와 프로퍼티,메소드를 구현하고 Refactoring 했다.<blockquote>
<p><code>테스트 케이스</code>를 작성하면서 전보다 제가 원하는 어떤 결과를 구체적으로 파악하게 된 것 같다. 이 테스트를 통과하기 위해서는 어떤 객체가 필요하고 그 객체가 어떤 메소드를 가지고 있어야 하고 어떤 프로퍼티를 가지고 있어야 하는지 먼저 큰 그림을 그려볼 수 있어서 좋았다. 처음에 깊게 생각하지 못한 부분 때문에 처음 설계와는 다르게 구현하게 됐지만, 그래도 중간 중간에 테스트 케이스를 먼저 수정하거나 추가하면서 그 테스트 케이스를 통과하기 위해 목적을 가지고 코드를 구현하는 것이 좋았다. 하지만 어떤 것을 테스트 해야 그 테스트를 통과한 메소드가 믿을만 해 지는 것인지는 아직 어렵다. 이 부분에 대해서는 계속해서 고민할 필요가 있다!</p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.02.13]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.12-yjxq69eu</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.12-yjxq69eu</guid>
            <pubDate>Thu, 13 Feb 2020 16:40:52 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘-한-일">오늘 한 일</h1>
<ol>
<li>Value Type(값형식)과 Reference Type(참조형식)이 메모리에 어떻게 저장되고 코드로 간단히 구현했을 때 어떻게 다른지에 대한 강의를 들었다.</li>
<li>테스트 코드를 수정했다.</li>
<li>접근 제한자에 대해서 들어보고 간단한 정의를 찾아보고 클래스나 구조체의 프로퍼티를 private으로 설정했다.</li>
<li>이후에 구조체의 프로퍼티를 직접 호출했던 테스트 코드를 수정했고, 그러면서 구조체에 필요한 메소드를 더 추가했다.</li>
<li>난수를 만들어내는 랜덤함수는 내가 생각했던 진짜 그 랜덤이 아니라는 걸 알게됐다.</li>
<li>random seed라는 걸 알게 됐다.</li>
<li>PR이 merge 됐다. 감동 😭  </li>
<li>피드백 받은 부분 수정하는데, 테스트 코드나 private 접근 제한자나 객체지향적으로 인스턴스의 속성을 숨기는(?)방식에 대해서 모르고 있어서 시간이 많이 걸려서 오늘 하루종일 한 것 같다.</li>
</ol>
<h1 id="느낀점">느낀점</h1>
<ol>
<li>시간이 되게 빠르게 간 날이었다. </li>
<li>한 건 없는데 시간만 간것같다.</li>
<li>잠이 안깬건지 피곤한건지 잠이 자고 싶은건지 코딩을 하고 싶은건지 공부를 하고 싶은건지 좀 모호한 날이었다.</li>
<li>매일 열심히 불타게 할 수는 없는 것 같다. 꾸준히 계속하자.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.02.12]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.12</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.12</guid>
            <pubDate>Wed, 12 Feb 2020 16:37:06 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘-한-일">오늘 한 일</h1>
<ol>
<li>Whale 브라우저를 다운받고 쓰기 시작했다. 공식문서를 읽을 때 텍스트를 드래그하면 파파고 번역 기능과 영어사전을 사용할 수 있어 용이하다. 하지만 번역이 파파고 앱(?) 만큼 퀄리티가 좋지는 않다. 그리고 다른 브라우저의 북마크나 자동 로그인 정보를 가지고 올 수 있어서 편리하다. 브라우저 홈에 간단한 형태지만 to do list가 있어서 좋다.</li>
<li>Sturcture 구조체의 immutable, mutating에 대한 공식 문서를 봤다.
<a href="https://docs.swift.org/swift-book/LanguageGuide/Methods.html#//apple_ref/doc/uid/TP40014097-CH15-ID239">https://docs.swift.org/swift-book/LanguageGuide/Methods.html#//apple_ref/doc/uid/TP40014097-CH15-ID239</a></li>
<li>safari 브라우저의 reading List 기능을 활용하기 시작했다.</li>
<li>객체지향에 맞지 않는 코드를 객체 지향에 맞게 리팩토링하는 방법에 대한 1시간 정도의 강의를 들었다.</li>
<li>셔플 알고리즘에 대해서 공부했다.</li>
</ol>
<h1 id="새롭게-알게-된-것">새롭게 알게 된 것</h1>
<p>1.<code>Fisher–Yates shuffle algorithm (original)</code></p>
<pre><code class="language-swift">var items = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;]
var shuffled = [String]();

for i in 0..&lt;items.count
{
    let rand = Int(arc4random_uniform(UInt32(items.count)))

    shuffled.append(items[rand])

    items.remove(at: rand)
}

print(shuffled)</code></pre>
<p>2.<code>Knuth Shuffle: Fisher–Yates shuffle algorithm (modern)</code>
<a href="https://developer.apple.com/videos/play/wwdc2018/406/?time=1289">https://developer.apple.com/videos/play/wwdc2018/406/?time=1289</a>
(동영상 &quot;Fisher–Yates shuffle&quot; 부분은 23:05 ~ )</p>
<p><strong>애플의 shuffle 메소드는 이 방식으로 구현됐다.</strong></p>
<pre><code class="language-swift">var items = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;]
var last = items.count - 1

while(last &gt; 0)
{
    let rand = Int(arc4random_uniform(UInt32(last)))

    print(&quot;swap items[\(last)] = \(items[last]) with items[\(rand)] = \(items[rand])&quot;)

    items.swapAt(last, rand)

    print(items)

    last -= 1
}</code></pre>
<p>original과 달리 두 개의 Collection이 필요없다. 
<a href="https://daheenallwhite.github.io/programming/algorithm/2019/06/27/Shuffle-Algorithm-Fisher-Yates/">https://daheenallwhite.github.io/programming/algorithm/2019/06/27/Shuffle-Algorithm-Fisher-Yates/</a>
3. <code>navie shuffle algorithm</code> vs <code>Fisher–Yates shuffle</code>
<a href="https://dyladan.me/abc/2016/01/20/shuffle/">https://dyladan.me/abc/2016/01/20/shuffle/</a>
<a href="https://gist.github.com/robertmryan/b002b7d524646fd677bb3979c89ec331">https://gist.github.com/robertmryan/b002b7d524646fd677bb3979c89ec331</a> </p>
<pre><code class="language-swift">extension Array {

    /// Simple implementation of Fisher-Yates

    mutating func shuffle() {
        for i in 0 ..&lt; count - 1 {
            let j = i + Int(arc4random_uniform(UInt32(count - i)))
            swapAt(i, j)
        }
    }

    /// Naive implementation that introduces biases

    mutating func shuffleBiased() {
        for i in 0 ..&lt; count {
            let j = Int(arc4random_uniform(UInt32(count)))
            swapAt(i, j)
        }
    }
}</code></pre>
<p>navie shuffle은 편향된 셔플 결과를 보이는 반면 Fisher-Yates shuffle은 항상 비슷한 셔플 결과를 보인다. </p>
<ol start="5">
<li><p><code>shuffle()</code>, <code>shuffled()</code>
<code>shuffle()</code>: <a href="https://developer.apple.com/documentation/swift/emptycollection/2995458-shuffle">https://developer.apple.com/documentation/swift/emptycollection/2995458-shuffle</a>
<code>shuffled()</code>:
<a href="https://developer.apple.com/documentation/swift/array/2994757-shuffled">https://developer.apple.com/documentation/swift/array/2994757-shuffled</a>
공통점 : Collection의 value들을 섞는다, 복잡도가 O(n)이다
차이점: shuffled 메소드는 셔플한 Collection을 반환한다.</p>
</li>
<li><p>recursive
<img src="https://i.imgur.com/K0XDHgS.png" alt="">
lhs와 rhs를 비교하는 메소드에 lhs == rhs 를 리턴하는 코드를 구현해서 다시 lhs와 rhs를 비교하는 메소드를 호출한다 -&gt; recursive.
따라서 lhs 와 rhs 의 어떤 속성을 비교했을 때 같다고 판단하는지를 메소드에 명시해줘야 한다.</p>
</li>
<li><p>xcode playgournd code folding ribbon -&gt; depth를 볼 수 있다.</p>
</li>
</ol>
<h1 id="적용해-본-것">적용해 본 것</h1>
<ol>
<li>TDD를 시도해봤다. 테스트 코드를 먼저 짜고 Red를 Green으로 바꾸고 Refector 해봤다. 테스트 코드를 짤 때 Given, When, Then으로 나눠서 짜봤다.</li>
</ol>
<h1 id="오늘의-시도와-결론">오늘의 시도와 결론</h1>
<p><strong>[ 실패 하나 😊 ]</strong>
테스트 코드를 먼저 작성해놔도 Equatable을 제대로 작성하지 않아서 시간을 많이 빼겼다. 오늘 새로 알게된 점 5번과 관련된 내용이다.</p>
<p><strong>[ 결론 👩‍💻 ]</strong>
일단 만들어놓고 print 찍어봐야지 하는 생각보다는 이 테스트가 동작이 되게 해야겠다는 식의 목표가 있는 접근이 좋았다. 다만 고민거리는 있었다. 테스트 함수는 여러 값 중에서 어떤 값을 테스트 하는 게 좋을지, 어디부터 어디까지 테스트해야 하는지. 앞으로 테스트 함수를 많이 짜봐야겠다.</p>
<p><strong>[ 성공 둘 😊 ]</strong>
크로스핏을 시작했다. </p>
<p><strong>[ 결론 👩‍💻 ]</strong>
각자 자기 페이스에 맞춰서 다같이 하는 운동이다. 그럼면에서 프로그래밍과 같은 것 같다. 2-3월은 그래서 운동을 하면서 마음을 계속 다잡아야겠다.</p>
<h1 id="궁금한-점">궁금한 점</h1>
<p><strong>🧐❓: 테스트 함수를 통과한 코드가 신뢰가 있으려면 테스트 코드로 어떤 걸 테스트 해야할까?</strong></p>
<p>😁 ❗️ 
... 찾아서 업데이트 할 예정.</p>
<h1 id="내일-할-일">내일 할 일</h1>
<p>내일 아침에 정리하겠습니다....ㅠ
일단 enum이나 테스트 코드, 랜덤이 진짜 랜덤인지 테스트하는 방법, set함수 등
객체 지향적으로 iOS 코드를 짠다는게 어떤건지 알아보기
View LifeCycle 알아보기
<a href="https://velog.io/@delmasong/Understand-the-View-Controller-LifeCycle">https://velog.io/@delmasong/Understand-the-View-Controller-LifeCycle</a>
View와 Window, view와 ViewController의 관계 알아보기 (공식문서 읽기)</p>
<h1 id="느낀점">느낀점</h1>
<p>시도해보고 실패한걸 시간 날렸다고 생각하지 말자. 
어차피 다 필요한 과정이고 삽질 하면서 배운다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Today I Learned 2020.02.11]]></title>
            <link>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.11</link>
            <guid>https://velog.io/@dev-lena/TIL-Today-I-Learned-2020.02.11</guid>
            <pubDate>Tue, 11 Feb 2020 16:50:51 GMT</pubDate>
            <description><![CDATA[<h1 id="오늘-한-일">오늘 한 일</h1>
<ol>
<li>어제 들은 강의(프로토콜, 델리게이트 패턴)에 대해서 다른사람에게 말해봤다. 설명까지는 아직 무리인 것 같다.</li>
<li><code>델리게이트 패턴</code>에 대해서 이전보다 이해가 됐다. 정확히는 위임자와 대리자의 관계를 이해했다.</li>
<li>카드덱 미션을 시작했다. </li>
<li><code>테스트 코드</code>를 먼저 짜고 코드 구현에 들어갔다. TDD에서 RGR(red-green-refactor)와 BDD(given-when-then)을 적용해서 해봤다. 내가 원하는 결과를 테스트 할 수 있는 테스트 코드를 먼저 짜고 테스트 코드가 green이 될 때 까지 일단 필요한 구조체와 메소드를 만들었다. 그리고 XCTAssertEqual이나 XCTAssertNotEqual을 쓰기 위해서 비교가 필요한 클래스에 extension으로 <code>Equatable</code> 프로토콜을 채택해서 구현했다.</li>
<li>API design guidlines을 읽었다.
<a href="https://swift.org/documentation/api-design-guidelines/#argument-labels">https://swift.org/documentation/api-design-guidelines/#argument-labels</a></li>
</ol>
<h1 id="새롭게-알게-된-것">새롭게 알게 된 것</h1>
<ol>
<li>테스트 코드 <code>code coverage</code> : 테스트 코드가 동작하는 범위와 동작하지 않은 범위(우측에 붉은 색으로 나타난다)를 알 수 있다.</li>
</ol>
<p><img src="https://i.imgur.com/wZoGIVg.png" alt=""></p>
<p><img src="https://i.imgur.com/S6emZjz.png" alt=""></p>
<ol start="2">
<li>어제 카드 클래스 안에 카드 정보(Suit+Rank)를 담고 있는 프로퍼티를 추가할지 고민했었는데  <code>CustomStringConvertible</code> 프로토콜로 해결. (어차피 카드 정보를 반환하는 메소드를 구현해야 했음.)</li>
</ol>
<ul>
<li><p>CustomStringConvertible 프로토콜</p>
<pre><code class="language-swift">struct Point: CustomStringConvertible {
  let x: Int, y: Int

  var description: String {
      return &quot;(\(x), \(y))&quot;
  }
}
</code></pre>
</li>
</ul>
<p>let p = Point(x: 21, y: 30)
let s = String(describing: p)
print(s)
// Prints &quot;(21, 30)&quot;</p>
<pre><code>출처 : 애플 공식 홈페이지

3. enum의 프로토콜. 
`CaseIterable` 프로토콜에 구현된 allCases 메소드를 사용할 수 있다.
* CaseIterable 프로토콜
```swift
enum CompassDirection: CaseIterable {
    case north, south, east, west
}

print(&quot;There are \(CompassDirection.allCases.count) directions.&quot;)
// Prints &quot;There are 4 directions.&quot;
let caseList = CompassDirection.allCases
                               .map({ &quot;\($0)&quot; })
                               .joined(separator: &quot;, &quot;)
// caseList == &quot;north, south, east, west&quot;</code></pre><h1 id="오늘의-시도와-결론">오늘의 시도와 결론</h1>
<p><strong>[ 성공 하나 😊 ]</strong>
테스트 코드를 먼저 작성하고 red를 green으로 바꾸면서 구현했다.(RGR)</p>
<p><strong>[ 결론 👩‍💻 ]</strong>
일단 만들어놓고 print 찍어봐야지 하는 생각보다는 이 테스트가 동작이 되게 해야겠다는 식의 목표가 있는 접근이 좋았다. 다만 고민거리는 있었다. 테스트 함수는 여러 값 중에서 어떤 값을 테스트 하는 게 좋을지, 어디부터 어디까지 테스트해야 하는지. 앞으로 테스트 함수를 많이 짜봐야겠다.</p>
<p><strong>[ 성공 둘 😊 ]</strong>
테스트 코드를 작성할 때 Given, When, Then을 나눠서 작성했다. (BDD)</p>
<p><strong>[ 결론 👩‍💻 ]</strong>
생각나는 대로 짜는 것 보다 주어진 Given, When, Then에 맞춰서 구현하는게 편했다.</p>
<h1 id="궁금한-점">궁금한 점</h1>
<p><strong>🧐❓: 테스트 함수는 여러 값 중에서 어떤 값을 테스트 하는 게 좋을까, 어디부터 어디까지 테스트해야 할까?</strong></p>
<p>😁 ❗️ 
... 찾아서 업데이트 할 예정.</p>
<p><strong>🧐❓: Dictionary나 Class, Struct, enum 데이터 구조가 갖는 각각의 장점은 뭘까? 각각의 선택 기준은 뭘까?</strong></p>
<p>😁 ❗️
... 찾아서 업데이트 할 예정.</p>
<h1 id="내일-할-일">내일 할 일</h1>
<ol>
<li>카드덱 구현</li>
<li>다음단계 포커딜러 구현</li>
<li>View와 Window / View와 ViewController의 관계 공부하기</li>
<li>델리게이트 패턴 정리하기 -&gt; 블로그 임시저장글로 만들기</li>
<li>구조체(struct)와 클래스(class) 차이 -&gt; 블로그에 올리기</li>
<li>immutable mutable 공부하기
<a href="https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html">https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html</a></li>
<li>다양한 shuffle 알고리즘에 대해 찾아본다.</li>
<li>클래스 메모리 관리 방식에 대해 학습한다. </li>
<li>메모리를 분석하는 디버깅 도구는 무엇이 있는지 학습한다.</li>
</ol>
<h1 id="느낀점">느낀점</h1>
<p>iOS 관련 문법은 애플 공식문서를 보는게 최고다.
프로토콜은 알면 알수록 도움된다. 다다익선.
알맞는 프로토콜을 채택할 수 있는게 중요한 것 같다. 
테스트 코드도 생각보다 고민이 많이 필요한 부분이다.
내일 열심히 해야겠다.</p>
<p>취미가 필요하다.</p>
]]></description>
        </item>
    </channel>
</rss>