Получить пользовательскую версию имени класса в swift (в objc NSStringFromClass было хорошо)
Есть ли эквивалент NSStringFromClass в Swift, который дает читаемую пользователем версию имени класса? Я попытался использовать его с собственным классом Swift, который я создал, но, как вы можете видеть, результат, похоже, является внутренним представлением компилятора имени класса:
println(NSStringFromClass(MyClass.self))
Результат:
_TtC5test7MyClass
Я попытался добавить к классу атрибут @objc и сделать его подклассом NSObject, но это не имеет никакого значения. Я обнаружил, что если я заменил MyClass классом Objective-C с тем же именем и импортировал его в заголовок моста, он даст мне "MyClass", но это не обязательно.
Другой вариант - создать протокол для этого, который каждый класс, который я хочу использовать таким образом, должен соответствовать:
protocol Nameable {
class var className: String { get }
}
Однако было бы проще иметь встроенный способ сделать это на языке.
Ответы
Ответ 1
новый формат на основе xcode 6 beta 5.
(имя_проект). (Имя_класс)
func getName(classType:AnyClass) -> String {
let classString = NSStringFromClass(classType.self)
let range = classString.rangeOfString(".", options: NSStringCompareOptions.CaseInsensitiveSearch, range: Range<String.Index>(start:classString.startIndex, end: classString.endIndex), locale: nil)
return classString.substringFromIndex(range!.endIndex)
}
Последние 6.3 Xcode Swift 1.2
если вам нужно расширение или вы можете поместить его на любой общий объект:
public extension NSObject{
public class var nameOfClass: String{
return NSStringFromClass(self).componentsSeparatedByString(".").last!
}
public var nameOfClass: String{
return NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
}
}
Ответ 2
Теперь вы можете просто сделать:
String(MyClass)
Ответ 3
На данный момент нет надежного способа сделать это. См. Комментарий разработчика Apple на https://devforums.apple.com/thread/227425
В настоящее время Swift не имеет большого значения для интроспекции.
Существует несколько механизмов интроспекции, которые используются для детские площадки. Я не знаю, предназначен ли это для API.
Некоторые Свифт методы и переменные могут быть рассмотрены с помощью Objective-C времени выполнения самоанализ. Вероятно, это лучшее решение сегодня.
В Swift есть понятие метатипа, несколько похожее на тип класса в Objective C. Его можно найти с помощью TypeName.self
, например:
class Foo {
@required init() {
}
}
var normalFoo : Foo = Foo()
var fooType : Foo.Type = Foo.self;
var fooFromMetatype : Foo = fooType();
Возможно, по времени выпуска метатипы будут включать в себя больше возможностей самоанализа. Я предлагаю подать запрос функции Radar для этого.
Ответ 4
В Swift 2 beta 4 вы можете получить информацию через объект типа:
let className = "\(String.self)" // gives: "Swift.String"
или если у вас есть экземпляр:
let s = "Hello World"
let className = "\(s.dynamicType)" // gives: "Swift.String"
Вы получаете результат Module.Class, например:
Swift.String
ABC.MyGenericClass<Swift.Int>
Забавно, что возвращаемый объект Type не соответствует протоколу CustomStringConvertible. Следовательно, он не имеет свойства описания, хотя шаблон "все еще делает правильные вещи".
P.S.: До b4 то же самое можно было бы выполнить с помощью отражения (obj.dynamicType).summary.
Ответ 5
Swift 3
type(of: self)
выводит Имя_файла .ClassName
String(describing: type(of: self))
выводит ClassName
Ответ 6
В Swift v3.0 это сработало для меня:
String.init(describing: self.self)
Ответ 7
Если вы хотите иметь только имя класса в swift, вы можете проанализировать строку, возвращаемую NSStringFromClass().
Это делается в nameOfClass.swift из репозитория INSwift Github:
https://github.com/indieSoftware/INSwift
Ответ 8
Теперь вы можете использовать следующее, чтобы получить имя класса в swift
let nameSpaceClassName = NSStringFromClass(RWTCountryPopoverViewController.self)
let className = nameSpaceClassName.componentsSeparatedByString(".").last! as String
Ответ 9
Это немного короче. Нет необходимости NSStringFromClass
MyObject.self.description().componentsSeparatedByString(".").last!
Ответ 10
Я предпочитаю использовать String(self.dynamicType)
Используйте его в моем проекте https://github.com/JakeLin/SwiftWeather/blob/e7165b0919dda53fd7fcba9b43fdfe150d73c6f8/SwiftWeather/ForecastView.swift#L135
Ответ 11
Вот пример Swift 3+, Xcode 8 + с кодом:
class MySuperbClass{
let a = 4
func getClassName() -> String? {
return String(describing: type(of:self)).components(separatedBy: ".").first
}
}
let className = String(describing: type(of:MySuperbClass.self)).components(separatedBy: ".").first
//className = "MySuperbClass"
let classNameFromObject = MySuperbClass().getClassName()
//classNameFromObject = "MySuperbClass"
Ответ 12
myObject.description().componentsSeparatedByString(" ").first!
Это не совсем то, что вы хотите - оно добавит нежелательные ведущие '<' и завершение ':'. Но когда я отлаживаю, я ценю скорость над аккуратностью, поэтому этот быстрый + грязный трюк сработал у меня.
Ответ 13
Swift 3
NSStringFromClass(self).components(separatedBy: ".").last!
Ответ 14
Swift 4
super.init(nibName:String(describing:MyClass.self), bundle: nil)