Ruft den Klassennamen des Objekts als Zeichenfolge in Swift ab

320

Abrufen des Klassennamens eines Objekts Stringmit:

object_getClassName(myViewController)

gibt so etwas zurück:

_TtC5AppName22CalendarViewController

Ich suche die reine Version : "CalendarViewController". Wie erhalte ich stattdessen eine bereinigte Zeichenfolge des Klassennamens?

Ich habe einige Versuche gefunden, Fragen dazu zu stellen, aber keine tatsächliche Antwort. Ist das überhaupt nicht möglich?

Bernd
quelle
alternativ… wie würde eine effektive Parserfunktion dafür aussehen?
Bernd
Wenn Sie überprüfen möchten, ob ein Objekt einer bestimmten Klasse angehört, lesen Sie diese Antwort .
Sinn-Angelegenheiten

Antworten:

527

Zeichenfolge aus einer Instanz :

String(describing: YourType.self)

Zeichenfolge von einem Typ :

String(describing: self)

Beispiel:

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"

Getestet mit class, structund enum.

Rudolf Adamkovič
quelle
4
Ist das wirklich der Fall? Gemäß den Dokumenten für String für diesen Initialisierer wird "ein nicht angegebenes Ergebnis automatisch von der Swift-Standardbibliothek bereitgestellt", wenn es nicht mit Streamable, CustomStringConvertible oder CustomDebugStringConvertible übereinstimmt. Wird der gewünschte Wert jetzt angezeigt, wird dies auch in Zukunft der Fall sein?
Tod Cunningham
3
Wenn Sie dies in Xcode 7.3.1 und Swift 2.2 verwenden, wird Folgendes erzeugt, was nicht ideal ist. '' let name = String (self) name String "<MyAppName.MyClassName: 0x ########>" ''
CodeBender
13
In Swift 3 ist die richtige Antwort, String(describing: MyViewController.self)wie in den folgenden Antworten angegeben , anzurufen .
AmitaiB
10
Aber es gibt "MyViewController.TYPE" zurück!
Orkenstein
3
@ RudolfAdamkovič Ja, das wäre wahr. Aber ich schreibe den Klassennamen nicht gerne explizit (was passiert, wenn ich die Klasse umbenenne Foo, Foo2aber Fooanderswo eine Klasse erstelle , kann dies den Code bremsen). Im Falle einer Unterklasse müssen Sie entweder type(of:)oder Type.selfje nach Bedarf verwenden. Ist wahrscheinlich type(of:)besser geeignet, um den Klassennamen zu erhalten.
Marián Černý
182

AKTUALISIERT AUF SWIFT 5

Über den Initialisierer können wir mithilfe der Instanzvariablen hübsche Beschreibungen von StringTypnamen erhalten und neue Objekte einer bestimmten Klasse erstellen

Wie zum Beispiel print(String(describing: type(of: object))). Wo objectkann eine Instanzvariable wie ein Array, ein Wörterbuch, ein Int, ein NSDateusw. sein?

Da dies NSObjectdie Stammklasse der meisten Objective-C-Klassenhierarchien ist, können Sie versuchen, eine Erweiterung für NSObjectzu erstellen, um den Klassennamen jeder Unterklasse von zu erhalten NSObject. So was:

extension NSObject {
    var theClassName: String {
        return NSStringFromClass(type(of: self))
    }
}

Oder Sie können eine statische Funktion erstellen, deren Parameter vom Typ ist Any(das Protokoll, dem alle Typen implizit entsprechen) und den Klassennamen als String zurückgibt. So was:

class Utility{
    class func classNameAsString(_ obj: Any) -> String {
        //prints more readable results for dictionaries, arrays, Int, etc
        return String(describing: type(of: obj))
    }
} 

Jetzt können Sie so etwas tun:

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

    }
}

Sobald wir den Klassennamen als String erhalten, können wir auch neue Objekte dieser Klasse instanziieren :

// 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)

Vielleicht hilft das jemandem da draußen!.

mauricioconde
quelle
2
Dies sollte die akzeptierte Antwort sein. Vielen Dank, ich habe nach einer Möglichkeit gesucht, den Klassennamen zu drucken, ohne ihn instanziieren zu müssen, und hier die Antwort gefunden. Danke drucken (String (BaseAsyncTask))
Bruno Coelho
4
classNameAsStringkann vereinfacht werden className, denn dieser "Name" impliziert seinen Typ. theClassNameähnelt der Geschichte von Facebook, die ursprünglich den Namen Facebook trägt.
DawnSong
"diccionary" ... die italienische Version von Swifts Wörterbuchsammlung:]
Andrew Kirna
Diese Lösung stellt den Projektnamen für jedes classTag voran, d ProjectTest.MyViewController. H. Wie werde ich diesen Projektnamen los? Ich möchte nur den Klassennamen.
Sazzad Hissain Khan
132

Swift 5

Hier ist die Erweiterung, um die typeNameals Variable abzurufen (arbeiten Sie sowohl mit dem Werttyp als auch mit dem Referenztyp).

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)
    }
}

Wie benutzt man:

// 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
nahung89
quelle
12
Irgendeine Idee, warum ich MyAppName.MyClassName daraus bekomme? Ich interessiere mich nur für MyClassName
Andrew
@ Andrew könnten Sie in Ihrem Fall genauer angeben? Ich verwende diese Erweiterung in vielen Projekten und alle reagieren wie beabsichtigt.
nahung89
1
Nun, wenn ich es von der Klasse selbst aufrufe, gibt es MyClassName zurück, aber wenn ich das in eine Methode einbinde, die die Klassennamenzeichenfolge zurückgibt und es von einer anderen Klasse aufruft, gibt es MyAppName.MyClassName zurück. Beim Durchsuchen habe ich festgestellt, dass alle Klassen implizit einen Namensraum haben. Wenn Sie sie also außerhalb Ihrer Klasse aufrufen, erhalten Sie MyAppName.MyClassName anstelle von MyClassName. Dann müssen Sie sich auf die Manipulation von Zeichenfolgen verlassen, um den Klassennamen zu erhalten.
Andrew
1
sehr nützliche Erweiterung
Hattori Hanzō
@ Andrew, nicht sicher, ob es aktuell funktioniert, aber ich erinnere mich, dass String (Beschreibung: Typ (von: Selbst)) verwendet wurde, um ModuleName.ClassName an einem Punkt zurückzugeben. Ich hatte mich aufgrund von getrennt. Zeichen und holte das letzte Objekt.
BangOperator
31

Swift 3.0

String(describing: MyViewController.self)

schlank
quelle
2
Eigentlich type(of: )ist da ein Overkill, String(describing: MyViewController.self)wird ausreichen
Alexander Vasenin
2
Dadurch wird eine Zeichenfolge wie <App_Name.ClassName: 0x79e14450> für mich erstellt, was nicht ideal ist
Doug Amos
Ist es nicht String.init(describing: MyViewController.self)?
Iulian Onofrei
2
@IulianOnofrei, das kannst du machen, aber das initist unnötig.
Shim
Entfernen Sie das AppName-Präfix vollständig! Danke
Yuchen
28

Ich schlage einen solchen Ansatz vor ( sehr schnell ):

// 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)"
}

Es wird weder Selbstbeobachtung noch manuelles Entwirren verwendet ( keine Magie! ).


Hier ist eine Demo:

// 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
werediver
quelle
Sie haben es in Swift 3.0 geändert. Jetzt können Sie String vontype(of: self)
Asad Ali
Aktualisiert auf Swift 3.
werediver
Ich denke, dies ist der beste Weg, um den Typnamen zu erhalten: jede Instanz einer Klasse, basierend auf NSObject, Enum, Typealiase, Funktionen, var-Eigenschaften und beliebigen Typen, sogar Konstanten. Für Typen müssen Sie .self verwenden. Beispiel: typeName (Int.self), typeName (true.self). Sie müssen sich auch nicht um den Projektnamen als Teil kümmern (z. B. AppProj. [Typname]). Großartig!
David.Chu.ca
23

Wenn Sie einen Typ haben Foo, erhalten Sie den folgenden Code "Foo"in Swift 3 und Swift 4:

let className = String(describing: Foo.self) // Gives you "Foo"

Das Problem mit den meisten Antworten hier ist, dass sie Ihnen "Foo.Type"als resultierende Zeichenfolge geben, wenn Sie keine Instanz des Typs haben, wenn das, was Sie wirklich wollen, gerecht ist "Foo". Im Folgenden finden Sie "Foo.Type", wie in einigen anderen Antworten erwähnt.

let className = String(describing: type(of: Foo.self)) // Gives you "Foo.Type"

Das type(of:)Teil ist unnötig, wenn Sie nur wollen "Foo".

sethfri
quelle
21

In Swift 4.1 und jetzt in 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)

Wenn Sie keine Instanz haben:

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

Wenn Sie eine Instanz haben:

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
McNight
quelle
14

Um den Namen einer Swift-Klasse von einem Objekt abzurufen, z. B. für das var-Objekt: SomeClass (), verwenden Sie

String(describing: type(of: object))

Verwenden Sie Folgendes, um den Namen einer Swift-Klasse von einem Klassentyp abzurufen, z. B. SomeClass.

String(describing: SomeClass.self)

Ausgabe:

"SomeClass"

Gurjit Singh
quelle
13

Sie können dies folgendermaßen versuchen:

self.classForCoder.description()
陈方涛
quelle
Dies funktioniert hervorragend, da es auch den vollständigen "Namespace" (das entsprechende Präfix für die Zielmitgliedschaft) enthält.
BonanzaDriver
Übrigens habe ich auch "String (self)" verwendet, wobei self eine Instanz von MyViewController ist, die auch funktioniert ... es liefert die gleichen Informationen ... Xcode 7.1.
BonanzaDriver
12

Sie können die Swift-Standardbibliotheksfunktion _stdlib_getDemangledTypeNamewie folgt verwenden:

let name = _stdlib_getDemangledTypeName(myViewController)
Jernej Strasner
quelle
@NeilJaff was meinst du mit "nur eine optionale Zeichenfolge"? Es gibt eine Zeichenfolge zurück und ist nicht optional.
Jernej Strasner
3
Dieser Ansatz gibt nicht die Namen von Klassen in privaten APIs zurück. Es wird der Name des ersten öffentlichen Basisklassennamens zurückgegeben.
Tylerc230
Ich erhalte die Nachricht: Verwendung des ungelösten Bezeichners '_stdlib_getDemangledTypeName'
Adobels
12

Verwenden Sie einfach die Zeichenfolgeninterpolation, um den Typnamen als Zeichenfolge in Swift 4 abzurufen (ich habe die früheren Versionen nicht überprüft):

"\(type(of: myViewController))"

Sie können .selffür einen Typ selbst und die type(of:_)Funktion für eine Instanz verwenden:

// Both constants will have "UIViewController" as their value
let stringFromType = "\(UIViewController.self)"
let stringFromInstance = "\(type(of: UIViewController()))"
Mischa Karpenko
quelle
8

Man kann auch Spiegel verwenden:

let vc = UIViewController()

String(Mirror(reflecting: vc).subjectType)

NB: Diese Methode kann auch für Strukturen und Aufzählungen verwendet werden. Es gibt einen displayStyle, der angibt, welcher Typ der Struktur:

Mirror(reflecting: vc).displayStyle

Die Rückgabe ist eine Aufzählung, so dass Sie:

Mirror(reflecting: vc).displayStyle == .Class
Paul Ardeleanu
quelle
Vielen Dank. Das hat bei mir funktioniert. Das einzige, was (zumindest unter iOS 9) ist, dass der subjectType mit ".Type" endete, also musste ich diesen Teil aus der Zeichenfolge entfernen.
Nikolay Suvandzhiev
8

Swift 5.1

Sie können jedoch Klassen-, Struktur-, Aufzählungs-, Protokoll- und NSObject-Namen abrufen Self.self.

print("\(Self.self)")
Victor Kushnerov
quelle
Beachten Sie, dass dies möglicherweise den String(describing: type(of: self))
Modulnamen vorstellt
7

Swift 3.0: Sie können eine Erweiterung wie diese erstellen. Sie gibt den Klassennamen ohne den Projektnamen zurück

extension NSObject {
    var className: String {
        return NSStringFromClass(self as! AnyClass).components(separatedBy: ".").last ?? ""
    }

    public class var className: String {
        return NSStringFromClass(self).components(separatedBy: ".").last ?? ""
    }
}
Ausnahme
quelle
Wenn ich versuche, dies zu verwenden, wird folgende Fehlermeldung angezeigt: Der Wert vom Typ 'ProjectName.MyViewController' (0x1020409e8) konnte nicht in 'Swift.AnyObject.Type' (0x7fb96fc0dec0) umgewandelt werden.
tylerSF
6

Sie können NSObjectProtocolin Swift 4 folgendermaßen erweitern:

import Foundation

extension NSObjectProtocol {

    var className: String {
        return String(describing: Self.self)
    }
}

Dadurch wird die berechnete Variable classNameALLEN Klassen zur Verfügung gestellt. Wenn Sie dies in einem print()In verwenden, CalendarViewControllerwird "CalendarViewController"in der Konsole gedruckt .

Siddharth Bhatt
quelle
4

Ich habe eine Weile nach dieser Antwort gesucht. Ich benutze GKStateMachine und beobachte gerne Statusänderungen und wollte eine einfache Möglichkeit, nur den Klassennamen zu sehen. Ich bin nicht sicher, ob es nur iOS 10 oder Swift 2.3 ist, aber in dieser Umgebung macht das Folgende genau das, was ich will:

let state:GKState?
print("Class Name: \(String(state.classForCoder)")

// Output:    
// Class Name: GKState
Troy
quelle
4

Sie können den Namen der Klasse erhalten, indem Sie Folgendes tun:

class Person {}
String(describing: Person.self)
Ale Mohamad
quelle
3

Um den Klassennamen als String zu erhalten, deklarieren Sie Ihre Klasse wie folgt

@objc(YourClassName) class YourClassName{}

Und erhalten Sie den Klassennamen mit der folgenden Syntax

NSStringFromClass(YourClassName)
Moin Uddin
quelle
3

Probieren Sie reflect().summaryClass self oder instance dynamicType aus. Entpacken Sie die Optionen, bevor Sie dynamicType abrufen. Andernfalls ist der dynamicType der optionale Wrapper.

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;

Die Zusammenfassung ist ein Klassenpfad mit beschriebenen generischen Typen. Versuchen Sie diese Methode, um einen einfachen Klassennamen aus der Zusammenfassung zu erhalten.

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;
}
nach vorne gezogen
quelle
3

Die oben genannten Lösungen haben bei mir nicht funktioniert. Das produzierte meistens die Themen, die in mehreren Kommentaren erwähnt werden:

MyAppName.ClassName

oder

MyFrameWorkName.ClassName

Diese Lösung funktionierte mit XCode 9, Swift 3.0:

Ich habe es classNameCleanedso benannt, dass der Zugriff einfacher ist und keine Konflikte mit zukünftigen className()Änderungen auftreten:

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()
    }

}

}}

Verwendungszweck:

NSViewController.classNameCleaned
MyCustomClass.classNameCleaned
Darkwonder
quelle
2

Swift 3.0 (macOS 10.10 und höher) können Sie von className erhalten

self.className.components(separatedBy: ".").last!
Thanh Vũ Trần
quelle
1
Soweit ich das beurteilen kann, gibt es in Swift-Klassen keine integrierte className-Eigenschaft. Hast du eine Unterklasse von etwas?
Shim
@shim className ist in Foundation deklariert, aber es scheint, dass es nur unter macOS 10.10 und höher verfügbar ist. Ich habe gerade meine Antwort bearbeitet.
Thanh Vũ Trần
1
Hm, das ist komisch. Warum sollten sie es nicht in iOS aufnehmen? Beachten Sie auch, dass es sich um eine Instanzmethode auf NSObject developer.apple.com/reference/objectivec/nsobject/… handelt
shim
2

Swift 5

 NSStringFromClass(CustomClass.self)
Adobels
quelle
2

Diese Art von Beispiel für die Klasse var. Geben Sie nicht den Namen des Bundles an.

extension NSObject {
    class var className: String {
        return "\(self)"
    }
}
Ivan Tkachenko
quelle
1

Wenn Ihnen der verstümmelte Name nicht gefällt, können Sie Ihren eigenen Namen diktieren:

@objc(CalendarViewController) class CalendarViewController : UIViewController {
    // ...
}

Auf lange Sicht wäre es jedoch besser zu lernen, den verstümmelten Namen zu analysieren. Das Format ist Standard und aussagekräftig und ändert sich nicht.

matt
quelle
Nein, ist es nicht, für meine Klasse wird es zurückgegeben (ExistentialMetatype) - das Verlassen auf undokumentiertes Laufzeitverhalten ist immer gefährlich, insbesondere für schnelle, da es sich noch in einem relativ frühen Stadium befindet.
Superarts.org
1

Manchmal geben die anderen Lösungen einen nicht nützlichen Namen, je nachdem, welches Objekt Sie betrachten möchten. In diesem Fall können Sie den Klassennamen wie folgt als Zeichenfolge abrufen.

String(cString: object_getClassName(Any!))

⌘ Klicken Sie auf die Funktion in xcode, um einige verwandte Methoden anzuzeigen, die ziemlich nützlich sind. oder überprüfen Sie hier https://developer.apple.com/reference/objectivec/objective_c_functions

Bob
quelle
1

Ich habe es type(of:...)mit Swift 3 auf dem Spielplatz versucht . Dies ist mein Ergebnis. Dies ist die Version im Codeformat.

print(String(describing: type(of: UIButton.self)))
print(String(describing: type(of: UIButton())))
UIButton.Type
UIButton
Lumialxk
quelle
Es ist verschwenderisch, eine Instanz zu instanziieren, nur um den Klassennamen zu bestimmen.
Sethfri
@sethfri Ich benutze dies, um den dynamischen Typ zu bestimmen.
Lumialxk
Ich verstehe immer noch nicht, warum Sie eine Instanz erstellen müssen, um die
Typinformationen
1

Swift 5 Sie können class_name als String mit String erhalten (Beschreibung: Self.self)

print(String(describing: Self.self))
yasinkbas
quelle
0

Ich benutze es in Swift 2.2

guard let currentController = UIApplication.topViewController() else { return }
currentController.classForCoder.description().componentsSeparatedByString(".").last!
Alexander Khitev
quelle
0

Swift 5.1: -

Sie können auch die generische Funktion verwenden, um den Klassennamen des Objekts als Zeichenfolge abzurufen

struct GenericFunctions {
 static func className<T>(_ name: T) -> String {
        return "\(name)"
    }

}

Rufen Sie diese Funktion wie folgt auf: -

let name = GenericFunctions.className(ViewController.self)

Viel Spaß beim Codieren :)

Dinesh Sharma
quelle
-1

In meinem Fall hat String (beschreibend: self) etwas zurückgegeben wie:

<My_project.ExampleViewController: 0x10b2bb2b0>

Aber ich hätte gerne so etwas wie getSimpleNameauf Android.

Also habe ich eine kleine Erweiterung erstellt:

extension UIViewController {

    func getSimpleClassName() -> String {
        let describing = String(describing: self)
        if let dotIndex = describing.index(of: "."), let commaIndex = describing.index(of: ":") {
            let afterDotIndex = describing.index(after: dotIndex)
            if(afterDotIndex < commaIndex) {
                return String(describing[afterDotIndex ..< commaIndex])
            }
        }
        return describing
    }

}

Und jetzt kehrt es zurück:

ExampleViewController

Das Erweitern von NSObject anstelle von UIViewController sollte ebenfalls funktionieren. Die obige Funktion ist auch ausfallsicher :)

Makalele
quelle
Das liegt daran, dass Sie eine Instanz des Klassennamens anstelle einer Klasse übergeben. Im obigen Beispiel sollten Sie ExampleViewController.self
Luke