runtime时的类型检测

2019-03-15  本文已影响0人  shoage

1.先来个例子
先声明一个协议 protocol  RouterProtocol
接着来个类遵循该协议extension K1ViewController: RouterProtocol
实例化K1ViewController   let ctl = K1ViewController()
根据实例获取类名:let name =NSStringFromClass(type(of: ctl))
根据类名获取类,方式一:
clz = NSClassFromString(name)
根据类名获取类,方式二:
let cchar = (name as NSString).utf8String
let clz2 =objc_getClass(cchar)

2.分析 
ctl是一个实例,print(ctl is K1ViewController) print(ctl is RouterProtocol)结果都会返回true
print(ctl is K1ViewController.Type)  print(ctl is RouterProtocol.Type)都会得到总是返回false的警告,因为实例是K1ViewController类型而不是K1ViewController.Type 类型,同理实例是RouterProtocol类型而不是RouterProtocol.Type类型

clz,NSClassFromString返回的是AnyClass,也即是AnyObject.Type,print(clz is K1ViewController)会得到总是返回false的警告,clz是AnyObject.Type类型,而K1ViewController是AnyObject类型两者并不是一个东西,            print(clz is K1ViewController.Type)才会返回true

clz2,objc_getClass返回Any类型,区别于NSClassFromString返回的AnyClass,clz跟clz2并不能直接相比较,但是clz2强转换AnyClass后,会发现跟clz是同一个东西。由于clz2是Any类型,所以print(clz2 is  K1ViewController)以及 print(clz2 is  K1ViewController.Type)编译器都不会有警告,但是clz2实质还是一个AnyObject.Type类型所以前者会返回false,后返回true

值得注意的是:OC里面的@protocol跟swift里的protocol是不同的,OC里的协议继承NSObject协议,而swift里没有这一说,因为这一差异,protocol.Type和protocol也会不一样,当protocol为OC里的@protocol类型时,protocol.Type和protocol什么区别,print(clz is RouterProtocol.Type)以及print(clz is RouterProtocol)都返回true;当protocol为纯swift时,后者会返回false

上一篇 下一篇

猜你喜欢

热点阅读