当前位置: 首页 > 工具软件 > Swift-T > 使用案例 >

Swift - 获取对象类型

叶琦
2023-12-01

我们一再强调,如果遵循规则的话,Swift 会是一门相当安全的语言:不会存在类型的疑惑,绝大多数内容应该能在编译期间就唯一确定。但是不论是Objective-C 里很多开发者早已习惯的灵活性,还是程序时间里总是千变万化的需求,都不可能保证一成不变。我们有时候也需要引入一定的动态特性。而其中最为基本却最为有用的技巧是获取任意一个实例类型

Objective-C 中我们可以轻而易举的做到这件事,使用 - class 方法就可以拿到对象的,我们甚至可以用NSStringFromClass 将它转换为一个能够打印出来的字符串:

NSDate *date = [NSDate date];
NSLog(@"%@", NSStringFromClass([date class]));

// 输出:
// __NSTaggedDate

在Swift 中,我们会发现不管是纯Swift 的class 还是NSObject 的子类,都没有像原来那样的class() 方法来获取类型了。对于NSObject 的子类,因为其实类的信息的存储方式并没有发生什么大的变化,因此我们可以求助于Objective-C运行时(runtime),来获取并按照原来的方式转换:

let date = Date()
let name: AnyClass! = object_getClass(date)
print(name!)

// 输出:
// __NSTaggedDate

其中object_getClass 是一个定义在Objective-C 的runtime 中的方法,它可以接受任意的Any? 并返回它的类型AnyClass? 。在Swift 中其实为了获取一个NSObject 或其子类的对象的实际类型,对这个调用其实有一个好看一些的写法,那就是public func type<T, Metatype>(of value: T) -> Metatype 方法。上面的代码用一种“更Swift”一些的语言转换一下,会是这个样子:

let date = Date()
let name = type(of: date)
print(name)

// 输出:
// Date

很好,似乎我们的问题能解决了。但是仔细想想,我们上面用的都是Swift 内建类型,要是换成Objective-C 的动态特性的话,会怎么样你?比如NSString

let string = NSString.init(string: "Hello")
let name = type(of: string)
print(name)

// 输出
// NSTaggedPointerString

完美

 类似资料: