Swift 4: тип (из: self) отличается при использовании private/fileprivate

Я реализовал расширение для NSObject, чтобы получить динамический тип моих объектов:

extension NSObject  {
    var dynamic_type : String {
        get {
            return String(describing: type(of: self))
        }
    }
}

Это отлично работает для публичных классов.

В классе с именем InitialState dynamic_type будет "InitialState" (это то, что я хочу). Но как только я изменю класс на private или fileprivate, это будет что-то вроде "(InitialState в _AF5C6D4A3B423A6F0735A7740F802E5A)" (круглые скобки также возвращаются)

Почему так и что означает часть после "in"? Как я могу получить простое имя класса для каждого типа класса? (публичный, частный, файловый)

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


person Community    schedule 17.01.2018    source источник
comment
Свойство className для NSObject уже есть.   -  person Alexander    schedule 17.01.2018
comment
Частные символы искажены дискриминатором, так что это, скорее всего, то, что вы видите в своем выводе. Но, в конце концов, строка, которую вы возвращаете из String(describing: type(of: self)), является деталью реализации, на нее не следует полагаться. Для чего именно вам это нужно?   -  person Hamish    schedule 17.01.2018
comment
@Alexander Этот метод не существует на iPhone, и я разрабатываю приложение для iOS :(   -  person    schedule 17.01.2018
comment
@Hamish Мне это нужно только для печати журналов. У меня есть конечный автомат, и каждое состояние наследуется от суперкласса (BaseState). В этом классе у меня есть несколько методов ведения журнала, но я хочу видеть в журналах точное состояние, а не только суперкласс. Это только для отладки, я не полагаюсь на ответ в своем коде. Но это выглядит странно с этой длинной строкой   -  person    schedule 17.01.2018
comment
Пример @Hamish: func handleMessage(_ msg: String) { log.error(handleMessage() не реализован для состояния (self.dynamic_type)) } (это метод в суперклассе)   -  person    schedule 17.01.2018
comment
@NomisHe Тогда вы могли бы использовать NSStringFromClass(type(of: self)); это даст вам имя, под которым среда выполнения Obj-C видит класс (которое можно изменить с помощью @objc(...)).   -  person Hamish    schedule 18.01.2018
comment
@Hamish: Это дает мне еще более странные результаты, например. _TtC18My_Module_NameP33_AF5C6D4A3B423A6F0735A7740F802E5A12InitialState вместо просто InitialState   -  person Simon Hessner    schedule 21.01.2018
comment
Ой, извините, совсем забыл про @objc(...). Если я напишу @objc(InitialState) перед именем класса, это сработает. Есть ли у этого побочные эффекты?   -  person Simon Hessner    schedule 21.01.2018
comment
@SimonH Кроме требования, чтобы класс наследовался от NSObject, не совсем так. Класс фактически доступен среде выполнения Obj-C независимо от атрибута @objc.   -  person Hamish    schedule 22.01.2018
comment
Итак, это хороший обходной путь, хотя было бы лучше, если бы был способ получить динамический тип без какой-либо дополнительной информации без необходимости аннотировать вручную... Возможно, в Swift 5: P   -  person Simon Hessner    schedule 22.01.2018