是否有一种方法可以在swift中打印变量的运行时类型?例如:
var now = NSDate()
var soon = now.dateByAddingTimeInterval(5.0)
println("\(now.dynamicType)")
// Prints "(Metatype)"
println("\(now.dynamicType.description()")
// Prints "__NSDate" since objective-c Class objects have a "description" selector
println("\(soon.dynamicType.description()")
// Compile-time error since ImplicitlyUnwrappedOptional<NSDate> has no "description" method
在上面的例子中,我正在寻找一种方法来显示变量“soon”的类型是ImplicitlyUnwrappedOptional<NSDate>,或至少NSDate!
我为自己开发的类(或您可以访问的类)找到了一个解决方案。
在你的对象类定义中放置以下计算属性:
var className: String? {
return __FILE__.lastPathComponent.stringByDeletingPathExtension
}
现在你可以像这样简单地调用对象的类名:
myObject.className
请注意,只有当类定义是在与您想要的类名称完全相同的文件中创建时,这才会起作用。
因为这是常见的情况,上面的答案应该做的大多数情况下。但在某些特殊情况下,你可能需要想出一个不同的解决方案。
如果你需要类(文件)本身的类名,你可以简单地使用这一行:
let className = __FILE__.lastPathComponent.stringByDeletingPathExtension
也许这个方法能帮助到一些人。
影响从String(description: type(of: self))返回的类名的另一个重要方面是Access Control。
考虑以下例子,基于Swift 3.1.1, Xcode 8.3.3(2017年7月)
func printClassNames() {
let className1 = SystemCall<String>().getClassName()
print(className1) // prints: "SystemCall<String>"
let className2 = DemoSystemCall().getClassName()
print(className2) // prints: "DemoSystemCall"
// private class example
let className3 = PrivateDemoSystemCall().getClassName()
print(className3) // prints: "(PrivateDemoSystemCall in _0FC31E1D2F85930208C245DE32035247)"
// fileprivate class example
let className4 = FileprivateDemoSystemCall().getClassName()
print(className4) // prints: "(FileprivateDemoSystemCall in _0FC31E1D2F85930208C245DE32035247)"
}
class SystemCall<T> {
func getClassName() -> String {
return String(describing: type(of: self))
}
}
class DemoSystemCall: SystemCall<String> { }
private class PrivateDemoSystemCall: SystemCall<String> { }
fileprivate class FileprivateDemoSystemCall: SystemCall<String> { }
如您所见,本例中的所有类都有不同级别的访问控制,这些访问控制会影响它们的String表示。如果类有私有或文件私有的访问控制级别,Swift似乎会附加一些与类的“嵌套”类相关的标识符。
PrivateDemoSystemCall和FileprivateDemoSystemCall的结果是附加了相同的标识符,因为它们都嵌套在同一个父类中。
我还没有找到一种方法来摆脱,除了一些hack替换或正则表达式函数。
这只是我的个人意见。