cleanUrl: /programming/type-of-type-of-swift

스위프트는 타입을 아주 중요하게 다루는 언어입니다. 어느 정도냐면.. 심지어 타입에도 타입이 있을 정도지요!! 그리고 이 타입의 타입을 메타타입이라고 부릅니다.

“타입의 타입”이 대체 뭔 소린지, 어디에 쓰일 수 있는지 바로 감이 오지 않을 수 있습니다. 타입만 해도 충분히 추상적인 개념인데, 그걸 또 한 번 더 추상화 시킨다니…뜬 구름 잡는 소리 처럼 느껴지는 것도 무리가 아닙니다.

하지만 차근차근 개념을 쫓아가다보면, 사실 별 것 아니란 걸 알게 되실 겁니다. 이번 포스트에서는 이 메타타입이 무엇이고 어떤 문제를 해결하는지 다뤄보도록 하겠습니다.

해결하고 싶은 문제

혹시 이런 상황에 부딪혀 보신 적 있으신가요?

class MyCell: UITableViewCell { ... }
// MyCell이란 이름의 xib파일도 있음

let myCellNib = UINib(nibName:"MyCell", bundle: nil)
tableView.register(myCellNib, forCellReuseIdentifier: "MyCell")

---

class YourCell: UITableViewCell { ... }
// YourCell이란 이름의 xib파일도 있음
let yourCellNib = UINib(nibName:"YourCell", bundle: nil)
tableView.register(yourCellNib, forCellReuseIdentifier: "YourCell")

// 기타 등등....

딱 봐도 많은 코드가 중복되고 있습니다. 이 때 이런 생각이 들지 않나요?

‘아… MyCell이라는 타입 자체를 변수로 쓸 수 있으면 좋겠다…’

좋은 소식입니다! Swift에서는 바로 그걸 할 수 있습니다!

MyCell.self

우리는 종종 MyClass.self 같은 표기를 만날 때가 있습니다. 대표적으로 Codable들을 Encoding하거나 Decoding할 때 만나게 되죠.

let myInfo = try? JSONDecoder().decode(MyClass.self, from: data)

이 때 MyClass.self에 해당되는 부분이, 바로 “MyClass”의 타입 자체의 변수 형태입니다.

“타입 자체의 변수 형태” 라고 하니까 감이 좀 잘 안 오는 면이 있습니다. 저는 아래 코드를 보니까 이해가 확 되더라고요.

class MyViewController: UIViewController {
    class var storyboardInstance: UIViewController {
        // eg. storyboardID 기반으로 ViewController생성
    }
    var someProperty: Int = 0
}

let myViewController = MyViewController()
print(myViewController.someProperty) // Print 0
print(myViewController.storyboardInstance) // Can't Access!!

print(MyViewController.someProperty) // Can't Access!!
print(MyViewController.storyboardInstance) // 평소 쓰던 class 변수 접근법
print(MyViewController.self.storyboardInstance) // **위의 거랑 같은 거!!**

그렇습니다. SomeClass.classVariable  SomeClass.self.classVariable의 줄임말 이었습니다. 우리는 SomeClass.self라는 표기법으로 Class변수(static 변수)에 접근 할 수도 있고, class메소드(static메소드)에도 접근 할 수 있습니다.

즉,  SomeClass.self의 표기법을 통해서, 우리는 **“class변수와 class메소드를 가지는 어떤 객체”**에 접근 할 수 있게 되는 것입니다.

type(of:type(of:)

한 걸음만 더 나아가 봅시다. 위의 코드에서 myViewController의 타입은 무엇일까요?