Swift 4: type(of:self).description() отличается от String(описание: type(of:self))

Мне нужно определить динамический тип моего объекта в методе, который реализован в суперклассе. Суперкласс называется BaseClient, и DisplayClient наследуется от него.

Мне нужно только имя класса, а не имя пакета. Вот что я пробовал:

print("1", String(describing: type(of: self))) // DisplayClient
print("2", type(of: self))                     // DisplayClient
print("3", type(of: self).description())       // package.DisplayClient
print("4", "\(type(of: self))")                // DisplayClient

Почему

 type(of: self).description()

return package.DisplayClient, в то время как другие возвращают только имя класса? Интересно, что вызывается внутри, когда я использую String(описание: type(of: self)). Я бы предположил, что это делает именно то, что делаю я (вызов description()).

Где я могу найти дополнительную информацию о том, как строки генерируются внутри?

В документах говорится:

Используйте этот инициализатор для преобразования экземпляра любого типа в предпочтительное представление в виде экземпляра String. Инициализатор создает строковое представление экземпляра одним из следующих способов, в зависимости от его соответствия протоколу:

  • Если экземпляр соответствует протоколу TextOutputStreamable, результат получается путем вызова instance.write(to: s) для пустой строки s.
  • Если экземпляр соответствует протоколу CustomStringConvertible, результатом будет instance.description.
  • Если instance соответствует протоколу CustomDebugStringConvertible, результатом будет instance.debugDescription.
  • Неопределенный результат автоматически предоставляется стандартной библиотекой Swift.

Но type(of: self) даже не имеет атрибута описания. У него есть только метод description(). Это какой-то особый случай, который обрабатывается компилятором по-разному?


person Simon Hessner    schedule 14.12.2017    source источник
comment
связанные: stackoverflow.com/questions/48306011/   -  person Simon Hessner    schedule 21.01.2018


Ответы (1)


Если ваш класс наследуется от NSObject, то type(of: self).description() вызывает метод класса NSObject.description():

class func description() -> String

Реализация этого метода в NSObject просто печатает имя класса.

и не задокументировано, включает ли это имя модуля или нет. Если ваш класс не наследуется от NSObject, то метод description() по умолчанию отсутствует.

С другой стороны,

print(String(describing: type(of: self))) // DisplayClient
print(type(of: self))                     // DisplayClient

оба печатают неполное имя типа, и

print(String(reflecting: type(of: self))) // package.DisplayClient
debugPrint(type(of: self) )               // package.DisplayClient

оба печатают полное имя типа, сравните Как получить имя типа Swift в виде строки с его пространством имен (или именем фреймворка) и Примечания к выпуску Xcode 7:

Имена типов и случаи перечисления теперь печатаются и преобразуются в строку без квалификации по умолчанию. debugPrint или String(reflecting:) по-прежнему можно использовать для получения полных имен.

person Martin R    schedule 14.12.2017
comment
Сейчас я использую String(описание: type(of: self)) и у меня это работает. Единственная проблема заключается в том, что это возвращает некоторую дополнительную информацию для классов, которые не являются общедоступными. Пример: (InitialState в _AF5C6D4A3B423A6F0735A7740F802E5A) возвращается для закрытого от файла класса InitialState. Но поскольку я использую эту информацию только для вывода на консоль (регистрации), это не является большой проблемой. Если я изменю класс на общедоступный, будет возвращен только InitialState (как и ожидалось) - person Simon Hessner; 21.01.2018
comment
связанные: stackoverflow.com/questions/48306011/ - person Simon Hessner; 21.01.2018