Bagaimana cara mencetak tipe atau kelas variabel di Swift?

335

Apakah ada cara untuk mencetak tipe runtime dari suatu variabel di swift? Sebagai contoh:

var now = NSDate()
var soon = now.dateByAddingTimeInterval(5.0)

println("\(now.dynamicType)") 
// Prints "(Metatype)"

println("\(now.dynamicType.description()")
// Prints "__NSDate" since objective-c Class objects have a "description" selector

println("\(soon.dynamicType.description()")
// Compile-time error since ImplicitlyUnwrappedOptional<NSDate> has no "description" method

Dalam contoh di atas, saya mencari cara untuk menunjukkan bahwa variabel "segera" adalah tipe ImplicitlyUnwrappedOptional<NSDate>, atau setidaknya NSDate!.

Matt Bridges
sumber
43
@JasonMArcher Katakan padaku bagaimana ini duplikat jika pertanyaan yang Anda tautkan diajukan 4 hari setelah ini?
akashivskyy
Ada sejumlah pertanyaan tentang pengujian jenis objek Swift atau membaca tipe objek Swift. Kami hanya menemukan pertanyaan terbaik untuk digunakan sebagai pertanyaan "master" untuk subjek ini. Duplikat yang disarankan memiliki jawaban yang jauh lebih menyeluruh. Ini bukan untuk mengatakan bahwa Anda melakukan sesuatu yang salah, hanya saja kami berusaha mengurangi kekacauan.
JasonMArcher
4
Duplikat yang disarankan tidak menjawab pertanyaan yang sama; Type.self tidak dapat dicetak ke konsol untuk keperluan debugging, itu dimaksudkan untuk digunakan untuk meneruskan ke fungsi lain yang mengambil Type sebagai objek.
Matt Bridges
2
OT: Sangat aneh bahwa Swift tidak menawarkan itu di luar kotak dan orang perlu bermain-main dengan perpustakaan C tingkat rendah seperti itu. Layak laporan bug?
qwerty_so
Kawan, saya telah memberikan jawaban saya di bawah ini. Silakan lihat dan beri tahu saya jika itu yang diharapkan.
DILIP KOSURI

Jawaban:

377

Pembaruan September 2016

Swift 3.0: Gunakan type(of:), mis. type(of: someThing)(Karena dynamicTypekata kunci telah dihapus)

Pembaruan Oktober 2015 :

Saya memperbarui contoh di bawah ini ke sintaks Swift 2.0 yang baru (mis. printlnDiganti dengan print, toString()sekarang String()).

Dari catatan rilis Xcode 6.3 :

@nschum menunjukkan dalam komentar bahwa catatan rilis Xcode 6.3 menunjukkan cara lain:

Ketik nilai sekarang cetak sebagai nama jenis demangled penuh ketika digunakan dengan println atau interpolasi string.

import Foundation

class PureSwiftClass { }

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

print( "String(myvar0.dynamicType) -> \(myvar0.dynamicType)")
print( "String(myvar1.dynamicType) -> \(myvar1.dynamicType)")
print( "String(myvar2.dynamicType) -> \(myvar2.dynamicType)")
print( "String(myvar3.dynamicType) -> \(myvar3.dynamicType)")

print( "String(Int.self)           -> \(Int.self)")
print( "String((Int?).self         -> \((Int?).self)")
print( "String(NSString.self)      -> \(NSString.self)")
print( "String(Array<String>.self) -> \(Array<String>.self)")

Output yang mana:

String(myvar0.dynamicType) -> __NSCFConstantString
String(myvar1.dynamicType) -> PureSwiftClass
String(myvar2.dynamicType) -> Int
String(myvar3.dynamicType) -> String
String(Int.self)           -> Int
String((Int?).self         -> Optional<Int>
String(NSString.self)      -> NSString
String(Array<String>.self) -> Array<String>

Pembaruan untuk Xcode 6.3:

Anda dapat menggunakan _stdlib_getDemangledTypeName():

print( "TypeName0 = \(_stdlib_getDemangledTypeName(myvar0))")
print( "TypeName1 = \(_stdlib_getDemangledTypeName(myvar1))")
print( "TypeName2 = \(_stdlib_getDemangledTypeName(myvar2))")
print( "TypeName3 = \(_stdlib_getDemangledTypeName(myvar3))")

dan dapatkan ini sebagai output:

TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String

Jawaban asli:

Sebelum Xcode 6.3 _stdlib_getTypeNamemendapat nama jenis variabel yang sudah diaduk. Entri blog Ewan Swick membantu menguraikan string ini:

misalnya _TtSisingkatan dari Inttipe internal Swift .

Mike Ash memiliki entri blog yang bagus yang membahas topik yang sama .

Klaas
sumber
2
Bagaimana kamu menemukan _stdlib_getTypeName()? REPL terintegrasi tidak lagi ada, swift-ide-testjuga tidak ada, dan pencetakan Xcode untuk modul Swift menghilangkan _nilai-nilai yang sebelumnya.
Lily Ballard
10
Sepertinya saya bisa mencari simbol dengan lldbcukup mudah di repl. Ada juga _stdlib_getDemangledTypeName(), dan _stdlib_demangleName().
Lily Ballard
1
Oh rapi, saya tidak menyadari imageitu jalan pintas target modules. Saya akhirnya menggunakan target modules lookup -r -n _stdlib_, yang tentu saja lebih baik dinyatakan sebagaiimage lookup -r -n _stdlib_ libswiftCore.dylib
Lily Ballard
1
FYI - Sepertinya toString (...) telah diganti dengan String (...).
Nick
6
Swift 3.0: Kata dynamicTypekunci telah dihapus dari Swift. Sebagai gantinya fungsi primitif baru type(of:)telah ditambahkan ke bahasa: github.com/apple/swift/blob/master/CHANGELOG.md
Szu
46

Sunting: Fungsi baru telah diperkenalkan di Swift 1.2 (Xcode 6.3) .toString

Anda sekarang dapat mencetak tipe demangled dari jenis apa pun menggunakan .selfdan contoh apa pun menggunakan .dynamicType:

struct Box<T> {}

toString("foo".dynamicType)            // Swift.String
toString([1, 23, 456].dynamicType)     // Swift.Array<Swift.Int>
toString((7 as NSNumber).dynamicType)  // __NSCFNumber

toString((Bool?).self)                 // Swift.Optional<Swift.Bool>
toString(Box<SinkOf<Character>>.self)  // __lldb_expr_1.Box<Swift.SinkOf<Swift.Character>>
toString(NSStream.self)                // NSStream

Coba panggil YourClass.selfdan yourObject.dynamicType.

Referensi: https://devforums.apple.com/thread/227425 .

akashivskyy
sumber
2
Saya menanggapi utas itu, tetapi saya akan menambahkan komentar saya di sini. Nilai-nilai tersebut bertipe "Metatype," tetapi tampaknya tidak ada cara yang mudah untuk mengetahui tipe objek Metatype yang diwakili, yang saya cari.
Matt Bridges
Mereka adalah tipe Metatype, dan mereka adalah kelas. Mereka mewakili kelas. Tidak yakin persis apa masalah Anda dengan itu. someInstance.dynamicType.printClassName()akan mencetak nama kelas.
File Analog
18
metode printClassName () hanyalah sebuah contoh metode yang mereka buat di salah satu sampel dalam dokumen, itu bukan panggilan API yang dapat Anda akses.
Dave Wood
4
FYI - Sepertinya toString (...) telah diganti dengan String (...)
Nick
33

Swift 3.0

let string = "Hello"
let stringArray = ["one", "two"]
let dictionary = ["key": 2]

print(type(of: string)) // "String"

// Get type name as a string
String(describing: type(of: string)) // "String"
String(describing: type(of: stringArray)) // "Array<String>"
String(describing: type(of: dictionary)) // "Dictionary<String, Int>"

// Get full type as a string
String(reflecting: type(of: string)) // "Swift.String"
String(reflecting: type(of: stringArray)) // "Swift.Array<Swift.String>"
String(reflecting: type(of: dictionary)) // "Swift.Dictionary<Swift.String, Swift.Int>"
Evgenii
sumber
1
Implementasi Swift 2 sangat baik dengan kasus enum. Adakah yang tahu apakah perilaku ini didokumentasikan / dijamin oleh Apple? Pustaka standar hanya mencakup komentar bahwa ini cocok untuk debugging ...
milos
30

Apakah ini yang Anda cari?

println("\(object_getClassName(now))");

Mencetak "__NSDate"

UPDATE : Harap dicatat ini sepertinya tidak lagi berfungsi pada Beta05

Haiku Oezu
sumber
2
Tidak berfungsi untuk kelas cepat. Mengembalikan "UnsafePointer (0x7FBB18D06DE0)"
aryaxt
4
Juga tidak berfungsi untuk kelas ObjC (setidaknya dalam Beta5), untuk NSManagedObject, saya hanya mendapatkan "Builtin.RawPointer = address"
Kendall Helmstetter Gelner
23

Xcode saya saat ini adalah Versi 6.0 (6A280e).

import Foundation

class Person { var name: String; init(name: String) { self.name = name }}
class Patient: Person {}
class Doctor: Person {}

var variables:[Any] = [
    5,
    7.5,
    true,
    "maple",
    Person(name:"Sarah"),
    Patient(name:"Pat"),
    Doctor(name:"Sandy")
]

for variable in variables {
    let typeLongName = _stdlib_getDemangledTypeName(variable)
    let tokens = split(typeLongName, { $0 == "." })
    if let typeName = tokens.last {
        println("Variable \(variable) is of Type \(typeName).")
    }
}

Keluaran:

Variable 5 is of Type Int.
Variable 7.5 is of Type Double.
Variable true is of Type Bool.
Variable maple is of Type String.
Variable Swift001.Person is of Type Person.
Variable Swift001.Patient is of Type Patient.
Variable Swift001.Doctor is of Type Doctor.
Matt Hagen
sumber
1
Bagus, tetapi pertanyaannya juga termasuk Opsional, output opsional ditetapkan Optional(...), sehingga kode Anda hanya akan kembali Optionalsebagai Jenis. Itu juga harus ditampilkan var optionalTestVar: Person? = Person(name:"Sarah")sebagai Opsional (Person) dan var with Person! as ImplisitlyUnwrappedOptional (Person)
Binarian
18

Pada Xcode 6.3 dengan Swift 1.2, Anda cukup mengkonversi nilai tipe menjadi demangled penuh String.

toString(Int)                   // "Swift.Int"
toString(Int.Type)              // "Swift.Int.Type"
toString((10).dynamicType)      // "Swift.Int"
println(Bool.self)              // "Swift.Bool"
println([UTF8].self)            // "Swift.Array<Swift.UTF8>"
println((Int, String).self)     // "(Swift.Int, Swift.String)"
println((String?()).dynamicType)// "Swift.Optional<Swift.String>"
println(NSDate)                 // "NSDate"
println(NSDate.Type)            // "NSDate.Type"
println(WKWebView)              // "WKWebView"
toString(MyClass)               // "[Module Name].MyClass"
toString(MyClass().dynamicType) // "[Module Name].MyClass"
kiding
sumber
Apakah kemungkinan arah lain di 1.2? Untuk menginisialisasi instance berdasarkan nama kelas?
user965972
@ user965972 Sejauh yang saya tahu saya tidak berpikir ada.
Kiding
17

Anda masih dapat mengakses kelas, melalui className(yang mengembalikan a String).

Sebenarnya ada beberapa cara untuk mendapatkan kelas, misalnya classForArchiver, classForCoder, classForKeyedArchiver(semua kembali AnyClass!).

Anda tidak bisa mendapatkan tipe primitif (primitif bukan kelas).

Contoh:

var ivar = [:]
ivar.className // __NSDictionaryI

var i = 1
i.className // error: 'Int' does not have a member named 'className'

Jika Anda ingin mendapatkan jenis primitif, Anda harus menggunakannya bridgeToObjectiveC(). Contoh:

var i = 1
i.bridgeToObjectiveC().className // __NSCFNumber
Leandros
sumber
Saya yakin itu primitif. Sayangnya Anda tidak bisa mendapatkan tipe primitif.
Leandros
Contoh-contoh itu sepertinya tidak bekerja di taman bermain. Saya mendapatkan kesalahan untuk primitif dan non-primitif.
Matt Bridges
cobalah untuk import Cocoa.
Leandros
9
className tampaknya hanya tersedia untuk NSObjects saat mengembangkan untuk OSX; itu tidak tersedia di iOS SDK untuk objek NSObjects atau "normal"
Matt Bridges
3
classNameadalah bagian dari dukungan AppleScript Cocoa dan jelas tidak boleh digunakan untuk introspeksi umum. Jelas itu tidak tersedia di iOS.
Nikolai Ruhe
16

Anda dapat menggunakan pantulan untuk mendapatkan informasi tentang objek.
Misalnya nama kelas objek:

var classname = mencerminkan (sekarang). ringkasan
Stan
sumber
Di Beta 6, ini memberi saya nama aplikasi + nama kelas dalam bentuk yang agak berantakan, tapi ini awal. +1 untuk reflect(x).summary- terima kasih!
Olie
tidak bekerja, mencetak baris kosong di Swift 1.2 Xcode 6.4 dan iOs 8.4
Juan Boero
13

Saya beruntung dengan:

let className = NSStringFromClass(obj.dynamicType)
mxcl
sumber
@ hdost dude tidak ada yang berhasil tetapi classForCoder bekerja.
Satheeshwaran
12

Xcode 8 Swift 3.0 menggunakan tipe (dari :)

let className = "\(type(of: instance))"
Hari Kunwar
sumber
10

Di Xcode 8, Swift 3.0

Langkah:

1. Dapatkan Jenis:

Pilihan 1:

let type : Type = MyClass.self  //Determines Type from Class

Pilihan 2:

let type : Type = type(of:self) //Determines Type from self

2. Konversi Jenis ke String:

let string : String = "\(type)" //String
pengguna1046037
sumber
8

Dalam Swift 3.0, Anda dapat menggunakan type(of:), sebagai dynamicTypekata kunci telah dihapus.

Bruno Serrano
sumber
7

SWIFT 5

Dengan rilis terbaru dari Swift 3 kita bisa mendapatkan deskripsi yang cukup tentang nama-nama jenis melalui Stringpenginisialisasi. Seperti, misalnya print(String(describing: type(of: object))). Di mana object bisa menjadi variabel instan seperti array, kamus, an Int, aNSDate , instance dari kelas kustom, dll.

Inilah jawaban lengkap saya: Dapatkan nama kelas objek sebagai string di Swift

Pertanyaan itu sedang mencari cara untuk mendapatkan nama kelas dari suatu objek sebagai string tetapi, juga saya mengusulkan cara lain untuk mendapatkan nama kelas dari variabel yang bukan subkelas NSObject. Ini dia:

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

Saya membuat fungsi statis yang mengambil sebagai parameter objek bertipe Anydan mengembalikan nama kelasnya sebagai String:).

Saya menguji fungsi ini dengan beberapa variabel seperti:

    let diccionary: [String: CGFloat] = [:]
    let array: [Int] = []
    let numInt = 9
    let numFloat: CGFloat = 3.0
    let numDouble: Double = 1.0
    let classOne = ClassOne()
    let classTwo: ClassTwo? = ClassTwo()
    let now = NSDate()
    let lbl = UILabel()

dan hasilnya adalah:

  • diccionary adalah kamus jenis
  • array bertipe Array
  • numInt adalah tipe Int
  • numFloat adalah tipe CGFloat
  • numDouble adalah tipe Double
  • classOne adalah tipe: ClassOne
  • classTwo adalah tipe: ClassTwo
  • sekarang adalah tipe: Tanggal
  • lbl adalah tipe: UILabel
mauricioconde
sumber
5

Saat menggunakan Cocoa (bukan CocoaTouch), Anda bisa menggunakan classNameproperti untuk objek yang merupakan subkelas dari NSObject.

println(now.className)

Properti ini tidak tersedia untuk objek Swift normal, yang bukan subclass dari NSObject (dan pada kenyataannya, tidak ada id root atau tipe objek di Swift).

class Person {
    var name: String?
}

var p = Person()
println(person.className) // <- Compiler error

Di CocoaTouch, saat ini tidak ada cara untuk mendapatkan deskripsi string dari jenis variabel yang diberikan. Fungsi serupa juga tidak ada untuk tipe primitif di Cocoa atau CocoaTouch.

Swift REPL mampu mencetak ringkasan nilai termasuk jenisnya, jadi ada kemungkinan introspeksi seperti ini akan dimungkinkan melalui API di masa mendatang.

EDIT : dump(object)sepertinya melakukan trik.

Matt Bridges
sumber
Bahkan pada Xcode 10 dan Swift 4.2, dump(object)sangat kuat. Terima kasih.
Alex Zavatone
5

Jawaban teratas tidak memiliki contoh kerja tentang cara baru dalam menggunakan ini type(of:. Jadi untuk membantu pemula seperti saya, ini adalah contoh kerja, diambil sebagian besar dari dokumen Apple di sini - https://developer.apple.com/documentation/swift/2885064-type

doubleNum = 30.1

func printInfo(_ value: Any) {
    let varType = type(of: value)
    print("'\(value)' of type '\(varType)'")
}

printInfo(doubleNum)
//'30.1' of type 'Double'
Joshua Dance
sumber
4

Saya sudah mencoba beberapa jawaban lain di sini tetapi jarak tempuh tampaknya sangat pada apa objek bawahan itu.

Namun saya menemukan cara Anda bisa mendapatkan nama kelas Object-C untuk objek dengan melakukan hal berikut:

now?.superclass as AnyObject! //replace now with the object you are trying to get the class name for

Berikut ini dan contoh bagaimana Anda akan menggunakannya:

let now = NSDate()
println("what is this = \(now?.superclass as AnyObject!)")

Dalam hal ini akan mencetak NSDate di konsol.

James Jones
sumber
4

Saya menemukan solusi ini yang semoga dapat bekerja untuk orang lain. Saya membuat metode kelas untuk mengakses nilai. Harap diingat bahwa ini hanya akan berfungsi untuk subkelas NSObject. Tapi setidaknya itu solusi yang bersih dan rapi.

class var className: String!{
    let classString : String = NSStringFromClass(self.classForCoder())
    return classString.componentsSeparatedByString(".").last;
}
DennyLou
sumber
4

Di XCode 6.3 terbaru dengan Swift 1.2, ini adalah satu-satunya cara yang saya temukan:

if view.classForCoder.description() == "UISegment" {
    ...
}
Joel Kopelioff
sumber
CATATAN: description () mengembalikan nama kelas dalam format <swift module name>.<actual class name>, jadi Anda ingin membagi string dengan a .dan mendapatkan token terakhir.
Matthew Quiros
4

Banyak jawaban di sini tidak berfungsi dengan Swift terbaru (Xcode 7.1.1 pada saat penulisan).

Cara saat ini untuk mendapatkan informasi adalah dengan membuat Mirrordan menginterogasinya. Untuk nama kelasnya sesederhana:

let mirror = Mirror(reflecting: instanceToInspect)
let classname:String = mirror.description

Informasi tambahan tentang objek juga dapat diambil dari Mirror. Lihat http://swiftdoc.org/v2.1/type/Mirror/ untuk detailnya.

Joseph Lord
sumber
Apa yang salah dengan jawaban stackoverflow.com/a/25345480/1187415 dan stackoverflow.com/a/32087449/1187415 ? Keduanya tampaknya bekerja dengan baik dengan Swift 2. (Belum memeriksa yang lain.)
Martin R
Saya suka ini sebagai solusi umum, tetapi mendapatkan "Mirror for ViewController" ("Mirror for" yang asing) - tunggu, sepertinya menggunakan ".subjectType" yang berfungsi!
David H
3

Di lldb pada beta 5, Anda bisa melihat kelas objek dengan perintah:

fr v -d r shipDate

yang menghasilkan sesuatu seperti:

(DBSalesOrderShipDate_DBSalesOrderShipDate_ *) shipDate = 0x7f859940

Perintah diperluas berarti sesuatu seperti:

Frame Variable(cetak variabel bingkai) -d run_target(perluas jenis dinamis)

Sesuatu yang berguna untuk diketahui adalah bahwa menggunakan "Frame Variable" untuk menampilkan nilai variabel menjamin tidak ada kode yang dieksekusi.

Kendall Helmstetter Gelner
sumber
3

Saya telah menemukan solusi untuk kelas yang dikembangkan sendiri (atau Anda dapat mengaksesnya).

Tempatkan properti yang dihitung berikut dalam definisi kelas objek Anda:

var className: String? {
    return __FILE__.lastPathComponent.stringByDeletingPathExtension
}

Sekarang Anda cukup memanggil nama kelas pada objek Anda seperti:

myObject.className

Harap dicatat bahwa ini hanya akan berfungsi jika definisi kelas Anda dibuat di dalam file yang diberi nama persis seperti kelas yang Anda inginkan.

Karena ini adalah kasus yang umum , jawaban di atas harus melakukannya untuk kebanyakan kasus . Tetapi dalam beberapa kasus khusus Anda mungkin perlu mencari solusi yang berbeda.


Jika Anda membutuhkan nama kelas di dalam kelas (file) itu sendiri, Anda cukup menggunakan baris ini:

let className = __FILE__.lastPathComponent.stringByDeletingPathExtension

Mungkin metode ini membantu beberapa orang di luar sana.

Astaga
sumber
3

Berdasarkan jawaban dan komentar yang diberikan oleh Klass dan Kevin Ballard di atas, saya akan menjawab:

println(_stdlib_getDemangledTypeName(now).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon?).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon!).componentsSeparatedByString(".").last!)

println(_stdlib_getDemangledTypeName(myvar0).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar1).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar2).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar3).componentsSeparatedByString(".").last!)

yang akan dicetak:

"NSDate"
"ImplicitlyUnwrappedOptional"
"Optional"
"NSDate"

"NSString"
"PureSwiftClass"
"Int"
"Double"
Vince O'Sullivan
sumber
Saya pikir ini adalah jawaban yang lebih baik.
Maschall
Saya akhirnya menggunakan Swift 1.2 sebagai berikut toString(self.dynamicType).componentsSeparatedByString(".").last!:, jelas saya berada dalam konteks objek dan dapat referensi self.
Joe
3
let i: Int = 20


  func getTypeName(v: Any) -> String {
    let fullName = _stdlib_demangleName(_stdlib_getTypeName(i))
    if let range = fullName.rangeOfString(".") {
        return fullName.substringFromIndex(range.endIndex)
    }
    return fullName
}

println("Var type is \(getTypeName(i)) = \(i)")
Alex Burla
sumber
3

Versi cepat 4:

print("\(type(of: self)) ,\(#function)")
// within a function of a class

Terima kasih @Joshua Dance

dengApro
sumber
3

Swift 4:

// "TypeName"
func stringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(describing: some) : String(describing: type(of: some))
    return string
}

// "ModuleName.TypeName"
func fullStringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(reflecting: some) : String(reflecting: type(of: some))
    return string
}

Pemakaian:

print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"
Desmond Hume
sumber
2

Tampaknya tidak ada cara umum untuk mencetak nama jenis dari jenis nilai arbitrer. Seperti yang telah dicatat orang lain, untuk instance kelas Anda dapat mencetakvalue.className tetapi untuk nilai-nilai primitif tampak bahwa pada saat runtime, informasi jenis hilang.

Misalnya, sepertinya tidak ada cara untuk mengetik: 1.something()dan keluar Intdengan nilai berapa pun something. (Anda dapat, sebagai jawaban lain menyarankan, penggunaan i.bridgeToObjectiveC().classNameuntuk memberikan petunjuk, tetapi __NSCFNumberadalah tidak benar-benar jenis i-. Hanya apa yang akan dikonversi ke ketika melintasi batas fungsi Objective-C panggilan)

Saya akan dengan senang hati terbukti salah, tetapi sepertinya pemeriksaan tipe dilakukan pada waktu kompilasi, dan seperti C ++ (dengan RTTI dinonaktifkan) banyak dari tipe informasi hilang saat runtime.

ipmcc
sumber
Bisakah Anda memberikan contoh penggunaan className untuk mencetak "NSDate" untuk variabel "sekarang" dalam contoh saya yang berfungsi di taman bermain Xcode6? Sejauh yang saya tahu, className tidak didefinisikan pada objek Swift, bahkan yang merupakan subclass dari NSObject.
Matt Bridges
Tampaknya 'className' tersedia untuk objek yang turun dari NSObject, tetapi hanya ketika dikembangkan untuk mac, bukan untuk iOS. Tampaknya tidak ada solusi sama sekali untuk iOS.
Matt Bridges
1
Ya, takeaway sebenarnya di sini adalah bahwa, dalam kasus umum, ketik informasi hilang saat runtime dengan cepat.
ipmcc
Saya ingin tahu bagaimana REPL mampu mencetak jenis nilai.
Matt Bridges
REPL hampir pasti ditafsirkan dan tidak dikompilasi, yang akan dengan mudah menjelaskannya
ipmcc
2

Ini adalah bagaimana Anda mendapatkan string tipe objek Anda atau Tipe yang konsisten dan memperhitungkan modul yang dimiliki definisi objek atau bersarang. Bekerja di Swift 4.x.

@inline(__always) func typeString(for _type: Any.Type) -> String {
    return String(reflecting: type(of: _type))
}

@inline(__always) func typeString(for object: Any) -> String {
    return String(reflecting: type(of: type(of: object)))
}

struct Lol {
    struct Kek {}
}

// if you run this in playground the results will be something like
typeString(for: Lol.self)    //    __lldb_expr_74.Lol.Type
typeString(for: Lol())       //    __lldb_expr_74.Lol.Type
typeString(for: Lol.Kek.self)//    __lldb_expr_74.Lol.Kek.Type
typeString(for: Lol.Kek())   //    __lldb_expr_74.Lol.Kek.Type
Igor Muzyka
sumber
2

Untuk mendapatkan jenis objek atau kelas objek di Swift , Anda harus menggunakan jenis (dari: objek Anda)

jenis (dari: objek Anda)

Rahul Panzade
sumber
1

Tidak persis apa yang Anda cari, tetapi Anda juga dapat memeriksa jenis variabel terhadap jenis Swift seperti:

let object: AnyObject = 1

if object is Int {
}
else if object is String {
}

Sebagai contoh.

PersuitOfPerfection
sumber
1

Xcode 7.3.1, Swift 2.2:

String(instanceToPrint.self).componentsSeparatedByString(".").last

leanne
sumber