Swift에서 개체의 클래스 이름을 문자열로 가져옵니다.
을 「」로 합니다.String
라이선스:
object_getClassName(myViewController)
는 다음과 같은 것을 반환합니다.
_TtC5AppName22CalendarViewController
순수 버전을 찾고 있습니다."CalendarViewController"
대신 클래스 이름의 정리된 문자열을 가져오려면 어떻게 해야 합니까?
나는 이것에 대한 몇 가지 질문 시도를 발견했지만, 실제 답은 찾지 못했다.전혀 불가능한가요?
인스턴스의 문자열:
String(describing: self)
유형에서 문자열:
String(describing: YourType.self)
예:
struct Foo {
// Instance Level
var typeName: String {
return String(describing: Foo.self)
}
// Instance Level - Alternative Way
var otherTypeName: String {
let thisType = type(of: self)
return String(describing: thisType)
}
// Type Level
static var typeName: String {
return String(describing: self)
}
}
Foo().typeName // = "Foo"
Foo().otherTypeName // = "Foo"
Foo.typeName // = "Foo"
「 」로 테스트 .class
,struct
★★★★★★★★★★★★★★★★★」enum
.
SWIFT 5로 갱신
instance 변수를 사용하여 유형 이름에 대한 자세한 설명을 얻을 수 있습니다.String
이니셜라이저 및 특정 클래스의 새 개체 만들기
, 「」라고 하는 것print(String(describing: type(of: object)))
서.어디에object
어레이, 딕셔너리, precision 등의 인스턴스 변수가 될 수 있습니다.Int
,a ,aNSDate
등등.
★★★★★★★★★★★★★★★★★★NSObject
의 Objective-C 입니다.Objective-C 의 할 수 .NSObject
NSObject
★★★★★★★★★★★★★★★★★★.
extension NSObject {
var theClassName: String {
return NSStringFromClass(type(of: self))
}
}
이 「유형」인 .Any
(모든 유형이 암묵적으로 준수하는 프로토콜) 및 클래스 이름을 String으로 반환합니다.다음과 같이 합니다.
class Utility{
class func classNameAsString(_ obj: Any) -> String {
//prints more readable results for dictionaries, arrays, Int, etc
return String(describing: type(of: obj))
}
}
이제 다음과 같은 작업을 수행할 수 있습니다.
class ClassOne : UIViewController{ /* some code here */ }
class ClassTwo : ClassOne{ /* some code here */ }
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Get the class name as String
let dictionary: [String: CGFloat] = [:]
let array: [Int] = []
let int = 9
let numFloat: CGFloat = 3.0
let numDouble: Double = 1.0
let classOne = ClassOne()
let classTwo: ClassTwo? = ClassTwo()
let now = NSDate()
let lbl = UILabel()
print("dictionary: [String: CGFloat] = [:] -> \(Utility.classNameAsString(dictionary))")
print("array: [Int] = [] -> \(Utility.classNameAsString(array))")
print("int = 9 -> \(Utility.classNameAsString(int))")
print("numFloat: CGFloat = 3.0 -> \(Utility.classNameAsString(numFloat))")
print("numDouble: Double = 1.0 -> \(Utility.classNameAsString(numDouble))")
print("classOne = ClassOne() -> \((ClassOne).self)") //we use the Extension
if classTwo != nil {
print("classTwo: ClassTwo? = ClassTwo() -> \(Utility.classNameAsString(classTwo!))") //now we can use a Forced-Value Expression and unwrap the value
}
print("now = Date() -> \(Utility.classNameAsString(now))")
print("lbl = UILabel() -> \(String(describing: type(of: lbl)))") // we use the String initializer directly
}
}
또한 클래스 이름을 String으로 취득하면 해당 클래스의 새 개체를 인스턴스화할 수 있습니다.
// Instantiate a class from a String
print("\nInstantiate a class from a String")
let aClassName = classOne.theClassName
let aClassType = NSClassFromString(aClassName) as! NSObject.Type
let instance = aClassType.init() // we create a new object
print(String(cString: class_getName(type(of: instance))))
print(instance.self is ClassOne)
어쩌면 이게 도움이 될지도 몰라!
스위프트 5
'내선번호'를 수 있는 확장자를 붙일 수 있는 입니다.typeName
변수로 사용할 수 있습니다(값 유형 또는 기준 유형 모두 사용).
protocol NameDescribable {
var typeName: String { get }
static var typeName: String { get }
}
extension NameDescribable {
var typeName: String {
return String(describing: type(of: self))
}
static var typeName: String {
return String(describing: self)
}
}
사용방법:
// Extend with class/struct/enum...
extension NSObject: NameDescribable {}
extension Array: NameDescribable {}
extension UIBarStyle: NameDescribable { }
print(UITabBarController().typeName)
print(UINavigationController.typeName)
print([Int]().typeName)
print(UIBarStyle.typeName)
// Out put:
UITabBarController
UINavigationController
Array<Int>
UIBarStyle
Swift 5.2:
String(describing: type(of: self))
Swift 3.0
String(describing: MyViewController.self)
이러한 접근법(매우 스위프티)을 제안합니다.
// Swift 3
func typeName(_ some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(type(of: some))"
}
// Swift 2
func typeName(some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(some.dynamicType)"
}
자기성찰이나 수동분할(마법 없음)을 사용하지 않습니다.
다음은 데모입니다.
// Swift 3
import class Foundation.NSObject
func typeName(_ some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(type(of: some))"
}
class GenericClass<T> {
var x: T? = nil
}
protocol Proto1 {
func f(x: Int) -> Int
}
@objc(ObjCClass1)
class Class1: NSObject, Proto1 {
func f(x: Int) -> Int {
return x
}
}
struct Struct1 {
var x: Int
}
enum Enum1 {
case X
}
print(typeName(GenericClass<Int>.self)) // GenericClass<Int>
print(typeName(GenericClass<Int>())) // GenericClass<Int>
print(typeName(Proto1.self)) // Proto1
print(typeName(Class1.self)) // Class1
print(typeName(Class1())) // Class1
print(typeName(Class1().f)) // (Int) -> Int
print(typeName(Struct1.self)) // Struct1
print(typeName(Struct1(x: 1))) // Struct1
print(typeName(Enum1.self)) // Enum1
print(typeName(Enum1.X)) // Enum1
「」라고 하는 타입이 .Foo
는 , 을 줄 것입니다."Foo"
3및 Swift4: Swift 3 swift Swift 4:
let className = String(describing: Foo.self) // Gives you "Foo"
은 이 이 당신에게 주는 입니다."Foo.Type"
의 인스턴스가 없는 으로서, 한 것은 「이러한 타입의 인스턴스가 없는 경우」뿐입니다."Foo"
아래는 다음과 같은 정보를 제공합니다."Foo.Type"
이치노
let className = String(describing: type(of: Foo.self)) // Gives you "Foo.Type"
type(of:)
당신이 원한다면 부품은 불필요합니다."Foo"
.
Swift 4.1에서 현재 Swift 4.2로:
import Foundation
class SomeClass {
class InnerClass {
let foo: Int
init(foo: Int) {
self.foo = foo
}
}
let foo: Int
init(foo: Int) {
self.foo = foo
}
}
class AnotherClass : NSObject {
let foo: Int
init(foo: Int) {
self.foo = foo
super.init()
}
}
struct SomeStruct {
let bar: Int
init(bar: Int) {
self.bar = bar
}
}
let c = SomeClass(foo: 42)
let s = SomeStruct(bar: 1337)
let i = SomeClass.InnerClass(foo: 2018)
let a = AnotherClass(foo: 1<<8)
주변에 인스턴스가 없는 경우:
String(describing: SomeClass.self) // Result: SomeClass
String(describing: SomeStruct.self) // Result: SomeStruct
String(describing: SomeClass.InnerClass.self) // Result: InnerClass
String(describing: AnotherClass.self) // Result: AnotherClass
주변에 인스턴스가 있는 경우:
String(describing: type(of: c)) // Result: SomeClass
String(describing: type(of: s)) // Result: SomeStruct
String(describing: type(of: i)) // Result: InnerClass
String(describing: type(of: a)) // Result: AnotherClass
스위프트 5.1
열거형, 및 은 NSObject를 통해 수 .Self.self
.
print("\(Self.self)")
개체에서 Swift 클래스의 이름을 가져오려면(예: var 객체의 경우)SomeClass(), 사용
String(describing: type(of: object))
SomeClass와 같은 클래스 유형에서 Swift 클래스의 이름을 가져오려면 다음을 사용합니다.
String(describing: SomeClass.self)
출력:
"어떤 클래스"
다음과 같이 시험해 볼 수 있습니다.
self.classForCoder.description()
Swift 4에서 유형 이름을 문자열로 가져오려면(이전 버전을 확인하지 않았습니다), 문자열 보간만 사용하십시오.
"\(type(of: myViewController))"
하시면 됩니다..self
, 및 「유형」에 대해서type(of:_)
다음 중 하나:
// Both constants will have "UIViewController" as their value
let stringFromType = "\(UIViewController.self)"
let stringFromInstance = "\(type(of: UIViewController()))"
표준 인 Swift를 할 수 ._stdlib_getDemangledTypeName
음음음같 뭇매하다
let name = _stdlib_getDemangledTypeName(myViewController)
Swift 5:
방법 1:
print("Class: \(String(describing: self)), Function: \(#function), line: \(#line)")
출력:
Class: <Test.ViewController: 0x7ffaabc0a3d0>, Function: viewDidLoad(), line: 15
방법 2:
print("Class: \(String(describing: type(of: self))), Function: \(#function), line: \(#line)")
출력:
Class: ViewController, Function: viewDidLoad(), line: 16
미러를 사용할 수도 있습니다.
let vc = UIViewController()
String(Mirror(reflecting: vc).subjectType)
NB: 이 메서드는 Structures 및 Enum에도 사용할 수 있습니다.displayStyle은 구조 유형을 나타냅니다.
Mirror(reflecting: vc).displayStyle
반환은 열거형이므로 다음을 수행할 수 있습니다.
Mirror(reflecting: vc).displayStyle == .Class
Swift 3.0: 다음과 같은 확장을 만들 수 있습니다.프로젝트 이름 없이 클래스 이름을 반환합니다.
extension NSObject {
var className: String {
return NSStringFromClass(self as! AnyClass).components(separatedBy: ".").last ?? ""
}
public class var className: String {
return NSStringFromClass(self).components(separatedBy: ".").last ?? ""
}
}
「 」를 연장할 수 .NSObjectProtocol
Swift 에서 : Swift 4 서 음 음 、 Swift 4 에 in、
import Foundation
extension NSObjectProtocol {
var className: String {
return String(describing: Self.self)
}
}
하면 된 변수가 됩니다.className
모든 클래스에서 사용할 수 있습니다.을 「」에서 .print()
CalendarViewController
합니다.를 인쇄합니다."CalendarViewController"
콘솔로 이동합니다.
다음과 같은 작업을 통해 클래스 이름을 얻을 수 있습니다.
class Person {}
String(describing: Person.self)
클래스 이름을 String으로 가져오려면 클래스를 다음과 같이 선언합니다.
@objc(YourClassName) class YourClassName{}
그리고 다음 구문을 사용하여 클래스 이름을 가져옵니다.
NSStringFromClass(YourClassName)
한동안 이 답을 계속 찾고 있었어요.저는 GKState Machine을 사용하고 있으며 상태 변화를 관찰하는 것을 좋아해서 클래스 이름만 쉽게 볼 수 있는 방법을 원했습니다.iOS 10과 Swift 2.3 중 어느 쪽인지는 잘 모르겠지만, 그 환경에서는 다음과 같은 기능이 바로 제가 원하는 대로 작동합니다.
let state:GKState?
print("Class Name: \(String(state.classForCoder)")
// Output:
// Class Name: GKState
★★를 해 보세요.reflect().summary
self instance dynamic Type dynamic type 。을 취득하기 을 언랩합니다. 않으면 wrapperdynamicType이 .dynamic Type typetypetype 。
class SampleClass { class InnerClass{} }
let sampleClassName = reflect(SampleClass.self).summary;
let instance = SampleClass();
let instanceClassName = reflect(instance.dynamicType).summary;
let innerInstance = SampleClass.InnerClass();
let InnerInstanceClassName = reflect(innerInstance.dynamicType).summary.pathExtension;
let tupleArray = [(Int,[String:Int])]();
let tupleArrayTypeName = reflect(tupleArray.dynamicType).summary;
요약은 범용 유형이 설명된 클래스 경로입니다.요약에서 간단한 클래스 이름을 가져오려면 이 방법을 사용하십시오.
func simpleClassName( complexClassName:String ) -> String {
var result = complexClassName;
var range = result.rangeOfString( "<" );
if ( nil != range ) { result = result.substringToIndex( range!.startIndex ); }
range = result.rangeOfString( "." );
if ( nil != range ) { result = result.pathExtension; }
return result;
}
위의 해결책은 나에게 효과가 없었다.는 주로 다음과 같은 몇 가지 코멘트에서 언급되는 문제를 제시했습니다.
My AppName 입니다.클래스명
또는
My Frame Work Name 。클래스명
이 솔루션은 XCode 9, Swift 3.0에서 동작했습니다.
는 그것을 가가라고 했다.classNameCleaned
접근하기 쉽고 미래와 충돌하지 않는다.className()
★★★★
extension NSObject {
static var classNameCleaned : String {
let className = self.className()
if className.contains(".") {
let namesArray = className.components(separatedBy: ".")
return namesArray.last ?? className
} else {
return self.className()
}
}
}
사용방법:
NSViewController.classNameCleaned
MyCustomClass.classNameCleaned
스위프트 5
NSStringFromClass(CustomClass.self)
클래스 var의 예를 다음에 나타냅니다.번들 이름은 포함하지 마십시오.
extension NSObject {
class var className: String {
return "\(self)"
}
}
Swift 3.0(macOS 10.10 이후), className에서 얻을 수 있습니다.
self.className.components(separatedBy: ".").last!
는 는 i i는노노 i i i i i.type(of:...)
스위프트3와 함께 플레이그라운드에서.이게 제 결과입니다.코드 포맷 버전입니다.
print(String(describing: type(of: UIButton.self)))
print(String(describing: type(of: UIButton())))
UIButton.Type
UIButton
이 솔루션은 모든 클래스에서 사용할 수 있습니다.
Swift 5 솔루션:
extension NSObject {
var className: String {
return String(describing: type(of: self))
}
class var className: String {
return String(describing: self)
}
}
용도:
class TextFieldCell: UITableVIewCell {
}
class LoginViewController: UIViewController {
let cellClassName = TextFieldCell.className
}
Swift 5.1 :-
개체의 클래스 이름을 문자열로 가져오는 일반 함수를 사용할 수도 있습니다.
struct GenericFunctions {
static func className<T>(_ name: T) -> String {
return "\(name)"
}
}
다음 명령을 사용하여 이 함수를 호출합니다.
let name = GenericFunctions.className(ViewController.self)
해피 코딩 :)
이름이 망가진 것이 마음에 들지 않는 경우는, 자신의 이름을 지정할 수 있습니다.
@objc(CalendarViewController) class CalendarViewController : UIViewController {
// ...
}
그러나 장기적으로 보면 엉망이 된 이름을 해석하는 방법을 배우는 것이 더 나을 것이다.형식은 표준이며 의미가 있으며 변경되지 않습니다.
보고자 하는 오브젝트에 따라 다른 솔루션에서 유용하지 않은 이름이 지정될 수 있습니다.이 경우 다음을 사용하여 클래스 이름을 문자열로 가져올 수 있습니다.
String(cString: object_getClassName(Any!))
② xcode의 함수를 클릭하면 매우 유용한 관련 메서드가 표시됩니다.또는 https://developer.apple.com/reference/objectivec/objective_c_functions 를 참조해 주세요.
언급URL : https://stackoverflow.com/questions/24494784/get-class-name-of-object-as-string-in-swift
'programing' 카테고리의 다른 글
호스트된 네트워크를 시작할 수 없습니다. (0) | 2023.04.21 |
---|---|
Go에서 빈 문자열을 테스트하는 가장 좋은 방법은 무엇입니까? (0) | 2023.04.21 |
Bash에서의 do-while 루프 에뮬레이트 (0) | 2023.04.21 |
의 쿼리 문자열을 해석 및 변경합니다.NET 코어 (0) | 2023.04.21 |
게시하는 동안 웹 앱을 오프라인으로 전환하려면 어떻게 해야 합니까? (0) | 2023.04.21 |