关于Objective-C API导入Swift时使用Any而非AnyObject的疑问
关于Objective-C API导入Swift时使用Any而非AnyObject的疑问
嗨,这个问题问到点子上了!其实背后主要和Objective-C与Swift的类型映射逻辑、API的设计兼容有关,我给你慢慢说清楚:
类型语义的对齐:Objective-C里像
NotificationCenter.addObserver、UIButton.addTarget这类API的参数(比如观察者、目标对象)原本是id类型,它的含义是“任意能响应Objective-C消息的对象”。在Swift早期版本中,id确实被映射为AnyObject(Swift中专门代表类实例的类型),但后来Apple把这些参数的导入类型改成了Any——这么做是为了更贴近Objective-C里id的宽泛语义,虽然Swift里Any包含了值类型和引用类型,但实际只有AnyObject(也就是兼容Objective-C的类实例)才能真正胜任观察者/目标的角色,因为只有它们能响应Objective-C的消息发送。兼容性的考量:有些老的Objective-C框架里,可能存在少数不严格继承自
NSObject的对象(虽然这种情况很少见),用Any而非AnyObject可以兼容这类边缘场景,避免导入API时出现不必要的类型限制。
针对你后面的两个问题:
- 当然有理由这么做!核心就是刚才说的——对齐Objective-C原生的类型语义,同时兼顾老框架的兼容性,让Swift开发者调用这些Objective-C API的体验更贴近原生Objective-C的使用方式。
- 完全不可能。Selector是Objective-C运行时的专属特性,它只能指向标记了
@objc的方法:要么是继承自NSObject的Swift类的方法(默认自动带有@objc特性),要么是你手动用@objc修饰的Swift类方法。如果尝试给非@objc的方法创建Selector,编译器会直接报错;就算强行绕过编译,运行时也会因为找不到对应的Objective-C方法而崩溃。
备注:内容来源于stack exchange,提问作者Pyrettt Pyrettt
相关产品推荐
相关产品推荐

