TIL - 2021.03.23 (Tue)

Youngwoo Lee·2021년 3월 25일
0

TIL

목록 보기
14/29
post-thumbnail

오늘 공부한 주제

  • 특강 : 새로운 지식을 나의 지식으로 만드는 방법 ( 연사 : Zedd)
  • Protocol Swift 공식문서 정독
  • 계산기 프로젝트 Step1에 대한 고뇌

공부 내용

Protocol

프로토콜은 특정 작업이나 기능에 적합한 method, property 및 요구사항에 대한 청사진을 정의한다. 그런 다음 프로토콜은 class, structure 또는 enum에 의해 채택되어 그러한 요구사항의 실제 구현을 제공할 수 있다. 프로토콜의 요구사항을 만족하는 모든 형식은 해당 프로토콜에 적합하다고 한다.

반드시 구현해야 하는 요구사항을 지정하는 것 외에도, 이러한 요구사항의 일부를 구현하거나 추가 기능을 구현하기 위해 프로토콜을 확장할 수 있습니다.

클래스 상속과 같이 프로토콜 채택을 표현할 때는

class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
    //class definition goes here
}

Property Requirements

  • 연산프로퍼티인지, 저장프로퍼티인지 명시하지 않는다
  • 오직 property의 이름과 type만 명시한다
  • 프로퍼티가 get, set 어느 것을 설정해야되는지만 명시함

프로퍼티가 get, set 요구한다면?

  • 상수 저장 프로퍼티는 충족하지 못함

  • 읽기 전용 연산 프로퍼티도 충족하지 못함

만약, 프로토콜이 오직 get만 요구하는 프로퍼티를 요구한다면?

  • 어떤 종류의 프로퍼티가 와도 상관 없다.

  • 그리고 get 뿐만 아니라 set도 구현해도 괜찮다

프로퍼티 요구사항은 무조건 변수 프로퍼티로 선언되어 진다.

타입 프로퍼티의 경우는 static을 명시해준다

프로토콜을 채택하고 충족하지 않으면 swift는 에러를 발생시킨다

Method Requirements

  • 인스턴스 method와 타입 method를 모두 요구할 수 있다
  • 본문이 없으나, 매개변수는 요구할 수 있다.
  • static method를 요구해도 static , class method로 모두 구현 가능하다
protocol SomeProtocol {
    static func someTypeMethod()
    func random(number: Int) -> Double
}

Mutating Method Requirements

enum 이나 structure 과 같은 값 타입들의 method들은 property를 변화시킬 경우 mutating 키워드를 사용한다. 프로토콜에서 이렇게 mutating method를 쓸 경우에는 mutating 키워드를 같이 표시해주면 된다.

But, 프로토콜에서 가변 메서드를 요구하지 않는다면, 값 타입의 인스턴스 내부 값을 변경하는 mutating 메서드는 구현이 불가능하다

Initializer Requirements

프로토콜은 init 또한 요구할 수 있는데, method와 같은 형식으로 매개변수를 요구할 수 있으며, body가 없다. 단, 반환 값은 원래 init() 자체에 없다.

Class Implementation of Protocol Initializer Requirements

상속이 없는 struct의 경우는 init을 구현할 때 관계 없지만, class의 경우는 protocol에서 요구 받은 이니셜라이저를 구현할 때 상속을 생각하여 required 키워드를 꼭 써줘야 한다.

protocol SomeProtocol {
    init(someProtocol: Int)
}
class SomeClass {
    init(someProtocol: Int) { } // Error
    required init(someProtocol: Int) { } // Correct
}

But, final class 의 경우는 다르다. final 자체가 상속을 하지 않는다는 것을 의미하기에 required를 init에 붙이지 않아도 된다

protocol SomeProtocol {
    init(someProtocol: Int)
}
final class SomeClass {
    init(someProtocol: Int) { } // Correct
}

그리고 프로토콜에서 요구하는 init이 상속을 받은 부모클래스에서 구현이 되어 있다면 그럴때는 required와 override를 같이 쓴다

protocol SomeProtocol {
    init()
}
class SomeSuperClass {
    init() {
        // initializer implementation goes here
    }
}
class SomeSubClass: SomeSuperClass, SomeProtocol {
    required override init() { }
}

Failable Initializer Requirements

실패 가능 이니셜라이저를 요구 받았을 경우, 실패 가능한 이니셜라이저 혹은 일반적인 이니셜라이저로 구현해도 상관 없다

protocol Named {
    var name: String { get }
    init?(name: String)
}

struct Animal: Named {
    var name: String
    init(name: String) {
        self.name = name
    }
}

struct Pet: Named {
    var name: String
    init?(name: String) {
        self.name = name
    }
}

class Person: Named {
    var name: String
    required init(name: String) {
        self.name = name
    }
}

class Student: Named {
    var name: String
    required init?(name: String) {
        self.name = name
    }
}

프로토콜의 상속과 클래스 전용 프로토콜

프로토콜도 클래스 처럼 서로 상속이 가능하다. 그리고 struct나 enum을 제외한 클래스을 상대로만 요구 프로토콜을 만들 수도 있다

protocol Readable {
    func read()
}

protocol ReadSpeakable: Readable {
    func speak()
}

class SomeClass: ReadSpeakable {
    func read() {

    }

    func speak() {

    }
}
protocol ClassOnlyProtocol: class {

}

struct SomeStruct: ClassOnlyProtocol {
    //오류 : 클래스 전용 프로토콜은 struct에서 불가능
}

특강 - 새로운 지식을 나의 지식으로 만드는 방법 ( 연사 : Zedd)

  • 목적과 목표를 뚜렷하게 만들어라!!
  • 사전 조사를 하자!
  • 모든 과정을 기록하자!
  • 피드백을 하자(퇴고)!

목표가 명확하면 무엇을 지금 당장 해야될지 보인다

→ SwiftUI롤 공부하겠어! 보다는 좀 더 작은 목표를 단기간에 세워서 빠르게 수행해라!

그리고 이 공부를 왜 해야되는지에 대한 근거가 생기면 좀 더 효과적이다! 왜 이 주제를 공부해야되는지 생각해보자!!

사전 조사

애플 공식문서를 보자... ⇒ iOS 공부에서 애플 공식문서는 시작과 끝이다!

학습을 시작하는 동시에 해당 주제에 대해서 기록하기 위해 블로그를 바로 켜자!

→ 애플 공식문서와 블로그를 동시에 키고, 학습과 기록을 동기화 시키자

피드백 퇴고를 하자!

→ 비록 본인이 작성했다고 할지라도 기록을 했다고 무조건 다 기억하는 것은 아니다. 주기적으로 퇴고를 하면서 배운 것에 대해서 remind하자!

Step1에 대한 고뇌

  • 이번 프로젝트는 Logic이 매우 까다롭다...

애플 기본 계산기의 경우 연산자 우선순위가 높은 연산자의 계산을 미리 처리해서 화면에 보여주는 방식이다.

중간에 어떻게 처리해야 될까??

  • 2진수 계산기와 10진수 계산기가 공통으로 가지는 속성이나 메서드가 있다

class로 구현 후 상속을 할지, protocol을 이용해서 채택해야할지 고민이다

  • 2진수 로직을 어떻게 처리할지 고민해보자, 계산기에 어떻게 표시되어야 사용자가 이해하기 편할까?

⇒ 해결 방안, 이번 프로젝트에서 class 가 더 어울리는지, 혹은 protocol이 더 어울리는지 protocol의 개념을 완벽히 이해하고 적용해보자!!

profile
iOS Developer Student

0개의 댓글