์ด์ ์ metatype์ ๋ํด ํ๋ ค๋ค์์๋๋ฐ, ์ด๋ฒ์ ๊ฐ๋จํ๊ฒ ์ ๋ฆฌํด๋ณด๋ คํ๋ค.
metatype์ด๋?
Swift์์ ์ฐ๋ฆฌ๋ ํน์ instance์ Type์ ์ ๊ทผํ ์ ์๋ค.
struct SomeStruct {
static let variable: String = "HI"
}
let someStruct = SomeStruct()
let someStructType = type(of: someStruct)
let someStructStaticVariable = someStructType.variable
print(someStructStaticVariable) // HI
๊ทธ๋ผ ์ฌ๊ธฐ์ someStructType
์ ์ด๋ค Type์ผ๊น? ์ด๋
์์ SomeStruct.Type
์ด๋ผ ๋์ด์๋ค. ๋ฐ๋ก ์ด๋
์์ด metatype์ด๋ค.
์ด๋ ๊ฒ ๋ฐ์ metaType์, ViewController.init()
์ ํ์ฌ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ฒ๋ผ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค. ์ด๋ฌํ ์ ์ ์ด์ฉํ๋ฉด ์ธ์๋ก metatype์ ๋ฐ์ ํด๋น metatype์ instance๋ฅผ ๋ง๋๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
class Apple {
required init() {}
}
func createApple<T: Apple>(appleType: T.Type) -> T {
return appleType.init()
}
let apple = self.createApple(appleType: Apple.self)
print(apple) // test.apple
์ฌ๊ธฐ์ ๊ทธ๋ฐ๋ฐ ์ธ์๋ก ๋ฃ์ด์ค ๋ Apple.self
๋ก ๋ฃ์ด์ฃผ์๋ค. ์ด๋
์์ ๋ญ๊น?
metatype์ Value
let a: Int = 3
์ฌ๊ธฐ์ a์ Type์ Int์ด๊ณ , Value๋ 3์ด๋ค. ๊ทธ๋ผ class, struct, enum ์์ฒด์ ์ ๊ทผํ ๋ ์์ type๊ณผ value๋ ์์ง ์์๊น?
Type | Value | ์์ | |
---|---|---|---|
Instance | Int, String | 3, โwansikโ | let a: Int = 3 |
Class, Struct ์์ฒด | Int.Type, String.Type | Int.self, String.self | let a: Int.Type = Int.self |
์ด๋ฐ ์ด์ ๋๋ฌธ์, createApple<T: Apple>(appleType: T.Type) -> T
์์ T.Type
์ class, struct, enum ์์ฒด์ metatype์ type์ ๋งํ๊ณ , ์ค์ ๊ฐ์ Apple.self
๋ก class, struct, enum ์์ฒด์ value๋ฅผ ๋ฃ์ด์ค ๊ฒ์ด๋ค.
Protocol metatype
๊ทธ๋ฐ๋ฐ protocol์์๋ ์ด ๋ ผ๋ฆฌ๊ฐ ํตํ์ง ์๋๋ค.
protocol MyProtocol {}
let metatype: MyProtocol.Type = MyProtocol.self // compile Error
์ด๋ MyProtocol.Type
์ด protocol ์์ฒด์ metatype์ type์ ๊ฐ๋ฆฌํค์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฅ? ๊ทธ๋ผ ๋ญ ๊ฐ๋ฆฌํฌ๊น? ์ด ํ๋กํ ์ฝ์ ์ค์ํ๊ณ ์๋ Type์ metatype์ ๊ฐ๋ฆฌํจ๋ค. ์ฆ, Protocol์ ์ถ์ ์ธํฐํ์ด์ค์ด๊ธฐ ๋๋ฌธ์, ์ค์ ์ด๋ฅผ ์ค์ํ๋ ๋
์์ด ๊ตฌํ์ฒด์ธ๋ฐ, ์ด๋
์์ metatype์ ๊ฐ๋ฆฌํจ๋ค๋ ๊ฒ์ด๋ค. Apple์ ์ด๋ฅผ existential metatype
, ์ค์กด ๋ฉํํ์
์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์ฝ๋๋ฅผ ๋ณด์.
protocol MyProtocol {
static func test()
}
struct MyType1: MyProtocol {
static func test() {
print("my type1")
}
}
struct MyType2: MyProtocol {
static func test() {
print("my type2")
}
}
let metatype1: MyProtocol.Type = MyType1.self
let metatype2: MyProtocol.Type = MyType2.self
metatype1.test() // my type1
metatype2.test() // my type2
์ฆ, ์ด ๊ฒฝ์ฐ metatype1, 2 ๋ณ์๋ MyProtocol์ static property ๋๋ method์๋ง ์ ๊ทผ ๊ฐ๋ฅํด์ง๋ค. ์๋ฐํ ๋งํ๋ฉด MyType struct์ ๊ตฌํ์ฒด๊ฐ ๋ถ๋ฆฐ๋ค. ๊ทธ๋์ ์ค์ ๊ตฌํ์ฒด์ ๊ฐ์ด ํธ์ถ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๊ทธ๋ผ protocol ์์ฒด์ type์ ์ด๋ป๊ฒ ์ ๊ทผํ ์ ์์๊น?
let protocolType: MyProtocol.Protocol = MyProtocol.self
์ด๋ ๊ฒ ํ๋ฉด ์ป์ ์๋ ์์ง๋ง, ์ค์ ๊ธฐ๋ณธ ๊ตฌํ์ ์ ๊ทผํด์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์ค์ง์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ๋ ์ด๋ ค์๋ณด์ธ๋ค.