概念
- 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 是雷同的。
参考文献 |