Swift中的Any、AnyObject、AnyClass先容

程序员 2024-9-25 12:34:45 76 0 来自 中国
概念


  • AnyObject:可以体现任何类范例的对象实例,全部类都隐式地依照 AnyObject;
  • Any:可以体现任何范例,包罗底子数据范例、罗列范例、布局体、函数范例等;
  • AnyClass:体现类的元范例,是AnyObject.Type的别名:界说typealias AnyClass = AnyObject.Type;
我们可以说AnyObject是Any的子集,Any和AnyObject都是Swift 的不确定的范例。
Any范例


  • 类、布局体大概罗列;
  • 元范例,好比 Int.self ;
  • 带有恣意范例元素的元组;
  • 闭包大概函数范例。
let mixed: [Any] = ["one", 2, true, (4, 5.3), { () -> Int in return 6 }]当你利用 Any 作为实例的具体范例时,你须要在访问其属性和方法之前把它转换成已知范例
if let first = mixed.first as? String {    print("The first item, '\(first)', is a string.")}// Prints "The first item, 'one', is a string."AnyObject范例

全部类都隐式依照AnyObject协议,这也限制了AnyObject是只适用于Class范例的缘故原由。AnyObject与OC中的id一样,它可以体现恣意类的实例,译器不会对向声明为 id 的变量举行范例查抄。因此,导入的OC范例经常利用AnyObject作为属性、方法参数和返回值的范例。
由于在Swift中的String,Array等范例都是struct范例界说的了,酿成了值范例,与OC中的引用范例不同,并不能是AnyObject来体现。因此在混编时须要利用AnyObject范例将Swift的值范例来转化为OC的引用范例。
看下面的例子:
let s: AnyObject = "This is a bridged string." as NSStringprint(s is NSString)// Prints "true"let v: AnyObject = 100 as NSNumberprint(type(of: v))// Prints "__NSCFNumber"再看一个例子
let swiftInt: Int? = 1let swiftString: String = "miao"        var array: [AnyObject] = []array.append(swiftInt as AnyObject) //Int,Array是布局体,恣意范例用Any,以是范例不符合,要强转范例array.append(swiftString as AnyObject)我们在这里声明白一个 Int 和一个 String,按理说它们都应该只能被 Any 代表,而不能被 AnyObject 代表的。但是你会发现这段代码是可以编译运行通过的。那是不是说实在 Apple 的编程指南堕落了呢?不是如许的,你可以打印一下 array,就会发现内里的元素实在已经酿成了 NSNumber 和 NSString 了,这里发生了一个主动的转换。在 Swift 和 Cocoa 中的这几个对应的范例是可以举行主动转换的。由于我们显式地声明白须要 AnyObject,编译器以为我们须要的的是 Cocoa 范例而非原生范例,而帮我们举行了主动的转换。
AnyClass

全部类范例隐式服从AnyClass协议
属于AnyObject.Type的别名:typealias AnyClass = AnyObject .Type
通过AnyObject.Type这种方式所得到的是一个元范例(Meta),声明时我们总是在范例的名称背面加上.Type,好比 A.Type 代表的是 A 这个范例的范例。也就是说,我们可以声明一个元范例来存储 A 这个范例自己,而在从 A 中取出其范例时,我们须要利用到 .self
class A {    class func method() {        print("Hello")    }}let typeA: A.Type = A.selftypeA,method()或let typeA: AnyClass = A.self(typeA as! A.Type).method()注:实在在 Swift 中,.self 可以用在范例背面取得范例自己,也可以用在某个实例背面取得这个实例自己。前一种方法可以用来得到一个体现该范例的值,这在某些时间会很有用;而后者由于拿到的实例自己,以是暂时好像没有太多须要这么利用的案例。
利用示例1
class IntegerRef {    @objc class func getDefaultValue() -> Int {        return 42    }}func getDefaultValue(_ c: AnyClass) -> Int? {    return c.getDefaultValue?()}print(getDefaultValue(IntegerRef.self))// Prints "Optional(42)"print(getDefaultValue(NSString.self))// Prints "nil"利用示例2
class MusicViewController: UIViewController {}class AlbumViewController: UIViewController {}let usingVCTypes: [AnyClass] = [MusicViewController.self,    AlbumViewController.self]func setupViewControllers(vcTypes: [AnyClass]) {    for vcType in vcTypes {        if vcType is UIViewController.Type {            let vc = (vcType as! UIViewController.Type).init()            print(vc)        }    }}setupViewControllers(usingVCTypes)
.Type 体现的是某个范例的元范例,而在 Swift 中,除了 class,struct 和 enum 这三个范例外,我们还可以界说 protocol。对于 protocol 来说,偶然间我们也会想取得接口的元范例。这时我们可以在某个 protocol 的名字背面利用 .Protocol 来获取,利用的方法和 .Type 是雷同的。
参考文献
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 18:22, Processed in 0.234219 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表