[swift] Swift에서 객체의 유형을 어떻게 알 수 있습니까?

프로그램이나 일부 경우를 이해하려고 할 때 실제로 어떤 유형인지 알아내는 것이 유용합니다. 디버거가 일부 유형 정보를 표시 할 수 있다는 것을 알고 있으며 일반적으로 유형 유추에 의존하여 해당 상황에서 유형을 지정하지 않아도 될 수는 있지만 여전히 Python과 같은 것을 원합니다.type()

dynamicType ( 이 질문 참조 )

업데이트 : 이것은 최신 버전의 Swift에서 변경되었으며 obj.dynamicType이제 동적 유형의 인스턴스가 아닌 유형에 대한 참조를 제공합니다.

이것은 가장 유망한 것으로 보이지만 지금까지 실제 유형을 찾을 수 없었습니다.

class MyClass {
    var count = 0
}

let mc = MyClass()

# update: this now evaluates as true
mc.dynamicType === MyClass.self

또한 새로운 객체 인스턴스화하는 클래스 참조를 사용하여 시도 하지 작업을하지만, 이상하게 나에게 내가 추가해야합니다라는 오류 준 required이니셜 라이저 :

공장:

class MyClass {
    var count = 0
    required init() {
    }
}

let myClass2 = MyClass.self
let mc2 = MyClass2()

그래도 주어진 객체의 유형을 실제로 발견하는 작은 단계 만 있습니다.

편집 : 나는 지금 관련이없는 많은 세부 사항을 제거했습니다. 관심이 있다면 편집 기록을보십시오 🙂



답변

스위프트 3 버전 :

type(of: yourObject)


답변

스위프트 2.0 :

이런 종류의 유형 내성 검사를 수행하는 올바른 방법은 Mirror 구조체를 사용하는 것입니다 .

    let stringObject:String = "testing"
    let stringArrayObject:[String] = ["one", "two"]
    let viewObject = UIView()
    let anyObject:Any = "testing"

    let stringMirror = Mirror(reflecting: stringObject)
    let stringArrayMirror = Mirror(reflecting: stringArrayObject)
    let viewMirror = Mirror(reflecting: viewObject)
    let anyMirror = Mirror(reflecting: anyObject)

그런 다음 Mirror 구조체subjectType 과 같이 속성을 사용하십시오 .

    // Prints "String"
    print(stringMirror.subjectType)

    // Prints "Array<String>"
    print(stringArrayMirror.subjectType)

    // Prints "UIView"
    print(viewMirror.subjectType)

    // Prints "String"
    print(anyMirror.subjectType)

그런 다음 다음과 같은 것을 사용할 수 있습니다.

    if anyMirror.subjectType == String.self {
        print("anyObject is a string!")
    } else {
        print("anyObject is not a string!")
    }


답변

dynamicType.printClassName코드는 스위프트 책의 예에서입니다. 사용자 정의 클래스 이름을 직접 얻는 방법은 없지만 is아래 표시된 키워드를 사용하여 인스턴스 유형을 확인할 수 있습니다. 이 예제는 또한 클래스 이름을 문자열로 원하는 경우 사용자 정의 className 함수를 구현하는 방법도 보여줍니다.

class Shape {
    class func className() -> String {
        return "Shape"
    }
}

class Square: Shape {
    override class func className() -> String {
        return "Square"
    }
}

class Circle: Shape {
    override class func className() -> String {
        return "Circle"
    }
}

func getShape() -> Shape {
    return Square() // hardcoded for example
}

let newShape: Shape = getShape()
newShape is Square // true
newShape is Circle // false
newShape.dynamicType.className() // "Square"
newShape.dynamicType.className() == Square.className() // true

참고 :
하위 클래스는 NSObject이미 자체 className 함수를 구현합니다. Cocoa를 사용하는 경우이 속성을 사용하면됩니다.

class MyObj: NSObject {
    init() {
        super.init()
        println("My class is \(self.className)")
    }
}
MyObj()


답변

현재 엑스 코드 6.0.1 (그들이 그것을 추가 할 때 적어도하지 않도록), 원래의 예는 이제 작동합니다 :

class MyClass {
    var count = 0
}

let mc = MyClass()
mc.dynamicType === MyClass.self // returns `true`

최신 정보:

원래 질문에 대답하기 위해 실제로 Objective-C 런타임을 일반 Swift 객체와 함께 성공적으로 사용할 수 있습니다.

다음을 시도하십시오 :

import Foundation
class MyClass { }
class SubClass: MyClass { }

let mc = MyClass()
let m2 = SubClass()

// Both of these return .Some("__lldb_expr_35.SubClass"), which is the fully mangled class name from the playground
String.fromCString(class_getName(m2.dynamicType))
String.fromCString(object_getClassName(m2))
// Returns .Some("__lldb_expr_42.MyClass")
String.fromCString(object_getClassName(mc))


답변

변수가 X 유형인지 또는 일부 프로토콜을 준수하는지 여부를 확인 해야하는 경우 is, 또는 as?다음과 같이 사용할 수 있습니다 .

var unknownTypeVariable =if unknownTypeVariable is <ClassName> {
    //the variable is of type <ClassName>
} else {
    //variable is not of type <ClassName>
}

이것은 isKindOfClassObj-C 와 동일 합니다.

그리고 이것은 conformsToProtocol또는isMemberOfClass

var unknownTypeVariable =if let myClass = unknownTypeVariable as? <ClassName or ProtocolName> {
    //unknownTypeVarible is of type <ClassName or ProtocolName>
} else {
    //unknownTypeVariable is not of type <ClassName or ProtocolName>
}


답변

스위프트 3 :

if unknownType is MyClass {
   //unknownType is of class type MyClass
}


답변

스위프트 3.0

String(describing: <Class-Name>.self)

스위프트 2.0-2.3

String(<Class-Name>)