如何获取嵌套 class 的字符串表示形式
How to get the string representation of a nested class
在我的反射库中EVReflection I have the following problem when class definitions are nested (class within a class). Below is a worked out case which can be found as a unit test here and The location in the library itself where the code needs to change is Here
I need to get the Internal Swift string representation of a nested
class for a property which is an array of that nested class.
您可以在下面看到一个单元测试,我可以在其中为作为另一个对象的 属性 公司获取正确的类型。它将输出 _TtCC22EVReflection_iOS_Tests13TestIssue114b10Company114
而不是 Company114
当我为朋友 属性 尝试同样的操作时,我的目标是输出如下内容:Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114>
我需要做什么才能得到它?
如您在测试中所见,我对值 valueType 进行了各种赋值。 None 这些作业有效。我只能得到 Array<User114>
或 Swift._EmptyArrayStorage
。
正如您在测试中看到的那样,如果我设置断点并在输出中执行 po window,我能够获得正确的输出。那么什么代码可以在我的代码中实现相同的功能?
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。我确实有一个数组扩展,它将 return 一个新的数组元素。但是我只能在将 Any 转换为 Array<NSObject>
时才能得到它,因此我的扩展将 return 一个 NSObject。所以我想得到一个像 Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114>
这样的字符串,然后我可以得到 <> 之间的部分,然后使用 NSClassFromString.
为它创建一个实例
String(reflecting: type(of: theValue))
Edwin Vermeer 更新:
对于所需的内部字符串表示形式的转换,我现在有以下功能(仍在草案中)
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
}
在我的反射库中EVReflection I have the following problem when class definitions are nested (class within a class). Below is a worked out case which can be found as a unit test here and The location in the library itself where the code needs to change is Here
I need to get the Internal Swift string representation of a nested class for a property which is an array of that nested class.
您可以在下面看到一个单元测试,我可以在其中为作为另一个对象的 属性 公司获取正确的类型。它将输出 _TtCC22EVReflection_iOS_Tests13TestIssue114b10Company114
而不是 Company114
当我为朋友 属性 尝试同样的操作时,我的目标是输出如下内容:Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114>
我需要做什么才能得到它?
如您在测试中所见,我对值 valueType 进行了各种赋值。 None 这些作业有效。我只能得到 Array<User114>
或 Swift._EmptyArrayStorage
。
正如您在测试中看到的那样,如果我设置断点并在输出中执行 po window,我能够获得正确的输出。那么什么代码可以在我的代码中实现相同的功能?
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。我确实有一个数组扩展,它将 return 一个新的数组元素。但是我只能在将 Any 转换为 Array<NSObject>
时才能得到它,因此我的扩展将 return 一个 NSObject。所以我想得到一个像 Swift.Array<_TtCC22EVReflection_iOS_Tests13TestIssue114b7User114>
这样的字符串,然后我可以得到 <> 之间的部分,然后使用 NSClassFromString.
String(reflecting: type(of: theValue))
Edwin Vermeer 更新: 对于所需的内部字符串表示形式的转换,我现在有以下功能(仍在草案中)
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
}