Swift 4中如何通过respondsToSelector验证HomeKit值的bytes方法
解决Swift 4中替代
respondsToSelector:的问题并转换代码 嘿,我来帮你把这段Objective-C代码转换成Swift 4版本,顺便搞定respondsToSelector:在Swift里的替代方案~
先回顾下你原来的Objective-C代码做了什么:
检查传入的
homeKitValue是否实现了bytes方法,如果是,就把它转成NSData,取出第一个字节作为uint64_t返回。
在Swift 4里,我们更偏向类型安全的写法,不需要依赖respondsToSelector:这种运行时检查,直接用类型转换就能搞定,而且更安全。
推荐的Swift 4转换代码
func getValue(from homeKitValue: Any) -> Any? { // 尝试将对象转换为Swift的Data类型(和OC的NSData桥接兼容) guard let data = homeKitValue as? Data, data.count > 0 else { return nil } // 直接通过下标访问第一个字节,转成UInt64返回 let value = UInt64(data[0]) return value }
代码说明
- Swift里
Data是NSData的桥接类型,直接用as? Data就能判断对象是否是数据类型,同时隐含了它支持字节访问,比respondsToSelector:更符合Swift的设计理念 - 加了
data.count > 0的判断,避免原代码中如果是空数据时解引用导致的崩溃,更健壮 - 返回值用
Any?对应OC的id类型,不符合条件时返回nil,和原逻辑一致
如果你一定要模拟respondsToSelector:的逻辑
如果某些特殊场景下你需要检查方法是否存在(不推荐,因为Swift更推崇类型检查),可以针对NSObject子类用responds(to:)方法:
func getValue(from homeKitValue: Any) -> Any? { // 先转成NSObject,再检查是否响应bytes方法 guard let obj = homeKitValue as? NSObject, obj.responds(to: #selector(getter: NSData.bytes)) else { return nil } let data = obj as! Data guard data.count > 0 else { return nil } let value = UInt64(data[0]) return value }
不过还是推荐第一种写法,它更符合Swift的类型安全特性,代码也更简洁~
内容的提问来源于stack exchange,提问作者lreddy
相关产品推荐
相关产品推荐

