Swift 5 : 메타타입 타입(Metatype Type)

버들비·2020년 8월 18일
0

메타타입이란 타입의 타입이다. 클래스 타입의 타입과 구조체 타입의 타입, 열거형 타입, 프로토콜 타입의 타입도 메타타입이다.

어떤 클래스 SomeClass 의 메타타입은 SomeClass.Type 이다.
어떤 프로토콜 SomeProtocol 의 메타타입은 SomeProtocol.Protocol 이다.

어떤 타입에 .self 를 붙이면 해당 타입을 어떤 값으로써 접근할 수 있다.
예를들어, SomeClass.self 는 SomeClass의 인스턴스를 리턴하는게 아니라, SomeClass 라는 것 자체를 리턴한다(프로토콜도 마찬가지).

type(of:) 메소드는 인스턴스의 클래스를 리턴한다.

class SomeClass {
	class func typeMethod(){
    	print("you've called type method")
    }
    static var typeProperty: String = "you've read type property"
}
var someInstance = SomeClass()
type(of: someInstance) // SomeClass.self
type(of: someInstance).typeMethod() // "you've called type method"
print(type(of: someInstance).typeProperty) // "you've read type property"
print(SomeClass.self.typeProperty) // "you've read type property"
print(SomeClass.typeProperty) // "you've read type property"

타입메소드나 타입프로퍼티에서 '타입'이라는 이름이 붙은 이유가 이것 때문이다. SomeClass.self는 SomeClass 와 같다.

이를 이용하면 컴파일때가 아니라 런타임때의 타입을 알 수 있다.

class SomeBaseClass {
    class func printClassName() {
        print("SomeBaseClass")
    }
}
class SomeSubClass: SomeBaseClass {
    override class func printClassName() {
        print("SomeSubClass")
    }
}
let someInstance: SomeBaseClass = SomeSubClass()
// The compile-time type of someInstance is SomeBaseClass,
// and the runtime type of someInstance is SomeSubClass
type(of: someInstance).printClassName()
// Prints "SomeSubClass"

type(of:) 메소드와 .self 를 이용해 AppDelegate 에서 view controller 를 다루는 예제.

let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
            if let controller = appDelegate?.window?.rootViewController {
                if let navigationController: UINavigationController = controller as? UINavigationController {
                    let viewControllers: [UIViewController] = navigationController.viewControllers
                    for viewController in  viewControllers {
                        if type(of: viewController) == SomeViewController.self {
                            print(viewController)
                            viewController.viewDidLoad()
                        }
                        if type(of: viewController) == OtherViewController.self {
                            print(viewController)
                            viewController.viewDidLoad()
                        }
                    }

프로젝트 내부의 view controller 들을 담은 배열 viewControllers를 만들고, if 문과 type(of:), .self 를 이용해 각 view controller 마다 다른 동작을 지시했다.


ref

https://sungdoo.dev/programming/swift의-타입과-타입의-타입/

0개의 댓글