Swift에서 객체의 유형을 어떻게 알 수 있습니까?
프로그램을 이해하려고 할 때 또는 일부 코너의 경우에는 어떤 유형의 프로그램인지 알아보는 것이 유용합니다.디버거가 당신에게 몇 가지 유형 정보를 보여줄 수 있다는 것을 알고 있고, 당신은 보통 그러한 상황에서 유형을 지정하지 않아도 되기 위해 유형 추론에 의존할 수 있지만, 여전히, 저는 파이썬의 것과 같은 것을 정말 갖고 싶습니다.type()
동적 유형(이 질문 참조)
업데이트: 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()
그래도 주어진 물체의 유형을 실제로 발견하기 위한 작은 단계에 불과합니다.
편집: 이제는 관련이 없는 많은 세부 사항을 제거했습니다. 관심이 있다면 편집 내역을 보십시오. :)
Swift 3 버전:
type(of: yourObject)
Swift 2.0:
이러한 유형의 내부 검사를 수행하는 적절한 방법은 미러 구조를 사용하는 것입니다.
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 함수를 이미 구현했습니다.코코아를 사용하는 경우 이 속성을 사용할 수 있습니다.
class MyObj: NSObject {
init() {
super.init()
println("My class is \(self.className)")
}
}
MyObj()
Xcode 6.0.1(최소한 언제 추가되었는지는 확실하지 않음)부터는 원래 예제가 다음과 같이 작동합니다.
class MyClass {
var count = 0
}
let mc = MyClass()
mc.dynamicType === MyClass.self // returns `true`
업데이트:
원래 질문에 답하기 위해 일반 Swift 개체와 함께 Objective-C 런타임을 성공적으로 사용할 수 있습니다.
다음을 시도합니다.
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>
}
과는▁ofent다에 해당합니다.isKindOfClass
Obj-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
}
Swift 3.0용
String(describing: <Class-Name>.self)
Swift 2.0 - 2.3의 경우
String(<Class-Name>)
권장되는 두 가지 방법은 다음과 같습니다.
if let thisShape = aShape as? Square
또는:
aShape.isKindOfClass(Square)
다음은 자세한 예입니다.
class Shape { }
class Square: Shape { }
class Circle: Shape { }
var aShape = Shape()
aShape = Square()
if let thisShape = aShape as? Square {
println("Its a square")
} else {
println("Its not a square")
}
if aShape.isKindOfClass(Square) {
println("Its a square")
} else {
println("Its not a square")
}
오래된 질문이지만 이는 내 요구사항에 적합합니다(Swift 5.x).
print(type(of: myObjectName))
댓글:저는 @JeremyLapointe가 어떻게 질문에 답하는지 모르겠습니다.사용.type(of:)
실제 유형이 보다 구체적인 하위 클래스인 경우에도 컴파일 시간 정보를 확인해야 작동합니다.이제 Swift 5.1에서 유형을 동적으로 쿼리할 수 있는 더 쉬운 방법이 있습니다.dynamicType
@Dash가 제안하는 것처럼.이 정보를 어디서 얻었는지에 대한 자세한 내용은 SE-0068을 참조하십시오. Swift Self를 클래스 구성원과 값 유형으로 확장합니다.
코드
스위프트 5.1
// Within an instance method context
Self.self
// Within a static method context
self
사할수있다를 할 수 .Self
포함하는 유형을 가리키는 약어로(의 경우).struct
s,enum
s, 그고리고그리.final class
타입)final
class
es)
설명.
제안서는 이 접근 방식이 왜 개선되는지 잘 설명합니다.dynamicType
:
소하는을
Self
에서는 다음과 같은 문제를 해결합니다.
dynamicType
Swift의 소문자 키워드 규칙에는 예외로 남아 있습니다.이러한 변화는 Swift의 새로운 표준과 맞지 않는 특별한 사례를 제거합니다.자아는 그 의도에서 더 짧고 명확합니다.은 거울을보를 반영합니다.self
현재 인스턴스를 나타냅니다.- 정적 멤버에 쉽게 액세스할 수 있습니다.형식 이름이 커지면 가독성이 저하됩니다.
MyExtremelyLargeTypeName.staticMember
타이핑하고 읽기가 불편합니다.- 유선 연결 형식 이름을 사용하는 코드는 형식을 자동으로 아는 코드보다 휴대성이 떨어집니다.
- 유형의 이름을 변경하는 것은 다음을 업데이트하는 것을(를)
TypeName
암호의 참조사용.self.dynamicType
시끄럽고 난해하다는 점에서 스위프트의 간결함과 명확함이라는 목표에 맞서 싸웁니다.:
self.dynamicType.classMember
그리고.TypeName.classMember
클래스 유형에서 비최종 멤버와 동의어를 사용할 수 없습니다.
" 되면 "Any"를 사용하기 에 "로해야 할 .is
(foo as Any) is SomeClass
매개 변수가 함수에 임의로 전달되면 다음과 같은 특수 유형에서 테스트할 수 있습니다.
func isADate ( aValue : Any?) -> Bool{
if (aValue as? Date) != nil {
print ("a Date")
return true
}
else {
print ("This is not a date ")
return false
}
}
사용 사례에 따라 다릅니다.그러나 "변수" 유형으로 유용한 작업을 수행하고 싶다고 가정해 보겠습니다. 스위트프.switch
진술은 매우 강력하며 원하는 결과를 얻는 데 도움이 될 수 있습니다.
let dd2 = ["x" : 9, "y" : "home9"]
let dds = dd2.filter {
let eIndex = "x"
let eValue:Any = 9
var r = false
switch eValue {
case let testString as String:
r = $1 == testString
case let testUInt as UInt:
r = $1 == testUInt
case let testInt as Int:
r = $1 == testInt
default:
r = false
}
return r && $0 == eIndex
}
이 경우 UInt, Int 또는 String일 수 있는 키/값 쌍이 포함된 간단한 사전을 준비합니다..filter()
사전에서 메소드, 값을 정확하게 테스트하고 문자열일 때만 테스트해야 합니다.스위치 명령문을 사용하여 이를 간편하고 안전하게 됩니다.Any형 변수에 9를 할당하여 Int용 스위치를 실행합니다.다음으로 변경해 보십시오.
let eValue:Any = "home9"
해 보세요...다시 시도해 보세요.에는 이는실행다니됩을 합니다.as String
//: Playground - noun: a place where people can play
import UIKit
class A {
class func a() {
print("yeah")
}
func getInnerValue() {
self.dynamicType.a()
}
}
class B: A {
override class func a() {
print("yeah yeah")
}
}
B.a() // yeah yeah
A.a() // yeah
B().getInnerValue() // yeah yeah
A().getInnerValue() // yeah
언급URL : https://stackoverflow.com/questions/24101450/how-do-you-find-out-the-type-of-an-object-in-swift
'programing' 카테고리의 다른 글
Azure DevOps의 다중 YAML 빌드 파이프라인 (0) | 2023.04.26 |
---|---|
asp.net :차트 핸들러 구성 [c:\TempImageFiles\] (0) | 2023.04.26 |
SQL Server에서 특정 문자 뒤와 앞에 있는 모든 항목 가져오기 (0) | 2023.04.26 |
Git에서 대소문자를 구분하는 파일 이름만 변경하려면 어떻게 해야 합니까? (0) | 2023.04.26 |
콘솔 출력을 반향하여 배트 스크립트의 파일로 전송하려면 어떻게 해야 합니까? (0) | 2023.04.26 |