Swift - .self .Self

뿌요·2022년 4월 16일
0
post-thumbnail

Dynamic MetaType vs. Static MetaType

.Type은 타입 지칭, .self 는 인스턴스

let intMetatype: Int.Type = Int.self

type(of:) 는 다이나믹 메타타입, .self 는 스태틱 메타타입

Protocol Metatype

protocol MyProtocol {}

let metatype: MyProtocol.Type = MyProtocol.self   // 컴파일 불가

컴파일 되지 않는 이유 : MyProtocol.Type 이 protocol 자체의 메타 타입을 뜻하지 않음

대신 protocol을 상속하고 있는 타입의 메타타입을 뜻함. 이것을 existensial metatype 이라 함

protocol MyProtocol {}

struct MyType: MyProtocol {}

let metatype: MyProtocl.Type = MyType.self    // 컴파일 성공

이 경우 metatype 프로퍼티는 MyProtocol의 class property 및 method 들만 접근 가능 (실제로는 MyType의 구현체가 불림)

protocol type 자체의 진짜 Metatype을 얻기 위해서는 .Protocol 을 붙이면 됨. (잘 안씀)

protocl MyProtocol {}

let protocolMetatype: MyProtocol.Protocol = MyProtocol.self

Self Type

Self type은 특정한 타입이 아님. .type 의 이름을 알아내거나 다시 쓸 필요없이 현재 type을 편하게 지칭할 수 있도록 도와줌

다만 protocol의 Self 는 해당 protocol을 따르는 최종 type을 지칭함.

where Self:

그렇다면 protocol ViewModelBindableType where Self: UIViewController 의 의미는

ViewModelBindableType을 따르는 Class/Struct 는 반드시 UIViewController를 상속받는 Class/Struct 여야 한다는 뜻이다.

이제 아래 코드를 분석해보자

protocol ViewModelBindableType where Self: UIViewController {
    associatedtype ViewModelType
    var viewModel: ViewModelType! { get set }
    func bindViewModel()

    mutating func bind(to viewModel: Self.ViewModelType) {
        self.viewModel = viewModel
        loadViewIfNeeded()
        bindViewModel()
        //개별 vc에서 bindViewModel()을 직접 호출할 필요가 없기때문에 코드가 단순해짐
    }
}

associatedtype 는 Generic 으로 viewModel 의 타입이 정해지면 결정된다.

어떤 ViewController 클래스가 ViewModelBindableType 을 구현한다면, viewModelbindViewModel을 해당 클래스에서 구현해야겠지만

bind(to viewModel: Self.ViewModelType)함수는 ViewController의 인스턴스에 직접 사용해줄 수 있다.

이때 인자로 들어가는 viewModel의 타입은 반드시 이 프로토콜을 상속하는 ViewController의 viewModel 타입과 일치해야 함을 알 수 있다 (associatedtype 이 제네릭이잖아)

이 코드의 결과로, 인자로 들어가는 viewModel은 ViewController의 viewModel(이 프로토콜을 상속 받아서 강제구현해야 하는)에 할당된다.

profile
iOS Developer

0개의 댓글