Получить пользовательскую версию имени classа в swift (в objc NSStringFromClass было хорошо)

Есть ли эквивалент NSStringFromClass в Swift, который дает читаемую пользователем версию имени classа? Я попытался использовать его с собственным classом Swift, который я создал, но, как вы можете видеть, результат, похоже, является внутренним представлением компилятора имени classа:

println(NSStringFromClass(MyClass.self)) 

Результат:

 _TtC5test7MyClass 

Я попытался добавить атрибут @objc к classу и сделать его подclassом NSObject, но это не имеет никакого значения. Я обнаружил, что если я заменил MyClass classом Objective-C с тем же именем и импортировал его в заголовок моста, он даст мне «MyClass», но это не обязательно.

Другой вариант – создать протокол для этого, который каждый class, который я хочу использовать таким образом, должен соответствовать:

 protocol Nameable { class var className: String { get } } 

Однако было бы проще иметь встроенный способ сделать это на этом языке.

новый формат на основе xcode 6 beta 5.

(Имя_проект). (Имя_class)

 func getName(classType:AnyClass) -> String { let classString = NSStringFromClass(classType.self) let range = classString.rangeOfString(".", options: NSStringCompareOptions.CaseInsensitiveSearch, range: Range(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! } } 

Теперь вы можете просто сделать:

 String(MyClass) 

Swift 3

type(of: self) prints ModuleName.ClassName

String(describing: type(of: self)) печатает ClassName

На данный момент нет надежного способа сделать это. См. Комментарий разработчика Apple по адресу https://devforums.apple.com/thread/227425

В настоящее время Swift не имеет особого значения для интроспекции.

Существует несколько интроспекционных машин, которые используются для игровых площадок. Я не знаю, предназначен ли это API.

Некоторые методы и переменные Swift можно исследовать с помощью самоанализа Objective-C. Скорее всего, это лучшее решение сегодня.

У Swift есть понятие метатипа, несколько аналогичное типу Class в Objective C. Вы можете найти его с помощью TypeName.self , например:

 class Foo { @required init() { } } var normalFoo : Foo = Foo() var fooType : Foo.Type = Foo.self; var fooFromMetatype : Foo = fooType(); 

Возможно, по времени выпуска метатипы будут включать в себя больше возможностей самоанализа. Я предлагаю подать запрос функции Radar для этого.

В 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 

Довольно забавно, что возвращаемый объект Type не соответствует протоколу CustomStringConvertible. Следовательно, он не имеет свойства описания, хотя шаблон «все еще делает правильную вещь».

PS: До b4 то же самое можно было бы выполнить с помощью рефлекса (obj.dynamicType) .summary.

В Swift v3.0 это сработало для меня:

 String.init(describing: self.self) 

Если вы хотите иметь только имя classа в swift, вы можете проанализировать строку, возвращаемую NSStringFromClass ().

Это делается в nameOfClass.swift из репозитория INSwift Github: https://github.com/indieSoftware/INSwift

Теперь вы можете использовать следующее, чтобы получить имя classа в swift

 let nameSpaceClassName = NSStringFromClass(RWTCountryPopoverViewController.self) let className = nameSpaceClassName.componentsSeparatedByString(".").last! as String 

Это немного короче. Нет необходимости в NSStringFromClass

 MyObject.self.description().componentsSeparatedByString(".").last! 

Вот пример 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" 

—– Обновлено —–

Как отметил @ThomasW, для Swift 4 нам нужно использовать String(describing:type(of:self))

—– Старый пост —-

Я предпочитаю использовать String(self.dynamicType)

Используйте его в своем проекте https://github.com/JakeLin/SwiftWeather/blob/e7165b0919dda53fd7fcba9b43fdfe150d73c6f8/SwiftWeather/ForecastView.swift#L135

 myObject.description().componentsSeparatedByString(" ").first! 

Это не совсем то, что вы хотите – это добавит нежелательные ведущие «<» и завершающие «:». Но когда я отлаживаю, я ценю скорость над аккуратностью, поэтому этот быстрый + грязный трюк сработал для меня.

Swift 3

 NSStringFromClass(self).components(separatedBy: ".").last! 

Swift 4

 super.init(nibName:String(describing:MyClass.self), bundle: nil) 
  • Переменные classа еще не поддерживаются.
  • Сохранение пользовательского classа Swift с помощью NSCoding для UserDefaults
  • Различия в синтаксисе NSDateComponents?
  • Получение «файла не обнаружено» в заголовке Bridging при импорте инфраструктур Objective-C в проект Swift
  • Swift - Захват ключа от NSViewController
  • Как сделать UILabel доступным?
  • как resize растрового изображения на iOS
  • Что является хорошим примером для различения fileprivate и private в Swift3
  • Ошибка "Thread 1: точка останова 2.1"
  • Как добавить ограничения программно с помощью Swift
  • Ограничение UIDatePicker датируется конкретным временем. Например, вход DOB в ограниченный возрастной предел
  • Давайте будем гением компьютера.