2016-10-12 12 views
1

В моей библиотеке отражений EVReflection У меня возникает следующая проблема, когда определения классов вложены (класс внутри класса). Ниже отработанный случай, который можно найти в качестве модульного теста here и расположения в самой библиотеке, где код должен изменить это HereКак получить строковое представление вложенного класса

Мне нужно, чтобы получить строковое представление внутреннего Swift вложенной класса для свойства, которое является массивом этого вложенного класса.

Ниже вы можете увидеть модульный тест, в котором я могу получить правильный тип для компании, которая является другим объектом. Он будет выводить _TtCC22EVReflection_iOS_Tests13TestIssue114b10Company114 вместо Company114

Когда я пытаюсь то же самое для друзей собственности моя цель состоит в том, что он выдает что-то вроде: Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114> Что я должен сделать, чтобы получить это?

Как вы можете видеть в тесте, у меня есть различные назначения значения valueType. Ни одно из этих заданий не работает. Я могу получить только Array<User114> или Swift._EmptyArrayStorage.

Как вы также можете видеть в тесте: если я установлю точку останова и сделаю po в окне вывода, я смогу получить правильный вывод. Итак, какой код будет реализован в моем коде?

class TestIssue114b: XCTestCase { 
    class User114: EVObject { 
     var company: Company114 = Company114() 
     var friends: [User114] = [] 
    } 

    class Company114: EVObject { 
     var name: String = "" 
     var address: String? 
    } 

    func testIssueNestedObjects() { 
     let x = User114() 
     print("type 1 = \(NSStringFromClass(type(of: x.company)))") // output = type 2 = _TtCC22EVReflection_iOS_Tests13TestIssue114b10Company114 
     print("type 2 = \(testIssueNestedObjects(x.friends))") 

    } 

    func testIssueNestedObjects(_ theValue: Any) -> String { 
     var valueType = "" 
     let mi = Mirror(reflecting: theValue) 
     valueType = NSStringFromClass(type(of: (theValue as! [NSObject]).getTypeInstance() as NSObject)) // NSObject 
     valueType = "\(type(of: theValue))" // Array<User114> 
     valueType = "\(mi.subjectType)"  // Array<User114> 
     valueType = ObjectIdentifier(mi.subjectType).debugDescription //"ObjectIdentifier(0x0000000118b4a0d8)" 
     valueType = (theValue as AnyObject).debugDescription  // <Swift._EmptyArrayStorage 0x10d860b50> 
     valueType = NSStringFromClass(type(of: theValue as AnyObject)) // Swift._EmptyArrayStorage 
     // set breakpont en enter this in output window: (lldb) po type(of: theValue) 
     // Ouput will be: Swift.Array<EVReflection_iOS_Tests.TestIssue114b.User114> 
     return valueType 
    } 
} 

Справочная информация: На самом деле конечная цель заключается в том, что я должен быть в состоянии создавать экземпляры объекта, который можно добавить в массив. Поскольку свойство массива доступно только в результате команды Mirror, переменная будет иметь тип Any. У меня есть расширение для массивов на месте, которое вернет новый элемент массива. однако я могу получить это только тогда, когда Any был добавлен в Array<NSObject>, и из-за этого мое расширение вернет NSObject. Поэтому я хотел бы получить строку, такую ​​как Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114>. Затем я могу получить части между <>, а затем создать экземпляр для этого с помощью NSClassFromString.

+0

'String (отражающие: тип (of: theValue)) ' – Jiri

+0

@Jiri Wow! это работает! Не могли бы вы ответить на ответ? Тогда я могу дать вам 250 очков бонуса! –

+0

Совершено, спасибо! – Jiri

ответ

3

String(reflecting: type(of: theValue))

обновление Эдвина Вермеер: Для требуемого преобразования к внутреннему представлению строки я теперь имею следующую функцию (еще в проекте)

public class func convertToInternalSwiftRepresentation(type: String) -> String { 
    if type.components(separatedBy: "<").count > 1 { 
     // Remove the Array or Set prefix 
     let prefix = type.components(separatedBy: "<") [0] + "<" 
     var subtype = type.substring(from: prefix.endIndex) 
     subtype = subtype.substring(to: subtype.characters.index(before: subtype.endIndex)) 
     return prefix + convertToInternalSwiftRepresentation(type: subtype) + ">" 
    } 

    if type.contains(".") { 
     var parts = type.components(separatedBy: ".") 
     if parts.count == 2 { 
      return parts[1] 
     } 
     let c = String(repeating:"C", count: parts.count - 1) 
     var rv = "_Tt\(c)\(parts[0].characters.count)\(parts[0])" 
     parts.remove(at: 0) 
     for part in parts { 
      rv = "\(rv)\(part.characters.count)\(part)" 
     } 
     return rv 
    } 
    return type 
} 
+0

Поскольку он возвращает EVReflection_iOS_Tests.TestIssue114b.User114, мне все равно нужно отдать его _TtCC22EVReflection_iOS_Tests13TestIssue114b7User114, но это преобразование в прямом направлении. Спасибо за этот ответ! –

+0

Простите, я только пытался добиться правильного вывода из 'testIssueNestedObjects (_ :)', указанного в последнем комментарии в этом методе. – Jiri

+0

Это прекрасно, вы многое помогли! Для меня это достаточно хорошо. –