swift 初探ANYCLASS,元类型和 .SELF

在 Swift 中能够表示 “任意” 这个概念的除了Any 和 AnyObject以外,还有一个AnyClass。AnyClass在 Swift 中被一个typealias所定义

typealiasAnyClass=AnyObject.Type

通过AnyObject.Type这种方式所得到是一个元类型 (Meta)。在声明时我们总是在类型的名称后面加上.Type,比如A.Type代表的是 A 这个类型的类型。也就是说,我们可以声明一个元类型来存储 A 这个类型本身,而在从A中取出其类型时,我们需要使用到.self:

classA{

}

let typeA:A.Type=A.self

其实在 Swift 中,.self可以用在类型后面取得类型本身,也可以用在某个实例后面取得这个实例本身。前一种方法可以用来获得一个表示该类型的值,这在某些时候会很有用;而后者因为拿到的实例本身,所以暂时似乎没有太多需要这么使用的案例。

了解了这个基础之后,我们就明白AnyObject.Type,或者说AnyClass所表达的东西其实并没有什么奇怪,就是任意类型本身。所以,上面对于A的类型的取值,我们也可以强制让它是一个AnyClass:

classA{

}

let typeA:AnyClass=A.self


这样,要是A中有一个类方法时,我们就可以通过typeA来对其进行调用了:

class A{ 

class func method( ){ 

print("Hello")}

let typeA:A.Type=A.self

typeA.method()// 或者

let anyClass:AnyClass=A.self(anyClassas!A.Type).method()

也许你会问,这样做有什么意义呢,我们难道不是可以直接使用A.method()来调用么?没错,对于单个独立的类型来说我们完全没有必要关心它的元类型,但是元类型或者元编程的概念可以变得非常灵活和强大,这在我们编写某些框架性的代码时会非常方便。比如我们想要传递一些类型的时候,就不需要不断地去改动代码了。在下面的这个例子中虽然我们是用代码声明的方式获取了MusicViewController和AlbumViewController的元类型,但是其实这一步骤完全可以通过读入配置文件之类的方式来完成的。而在将这些元类型存入数组并且传递给别的方法来进行配置这一点上,元类型编程就很难被替代了:

class  MusicViewController:UIViewController{

}

class AlbumViewController:UIViewController{

}

let usingVCTypes:[AnyClass]=[ MusicViewController.self,AlbumViewController.self]

func setupViewControllers(vcTypes:[AnyClass]){

for vcType  in  vcTypes{

if vcType isUIViewController.Type{

let vc=(vcTypeas!UIViewController.Type).init()

print(vc)}}

}

setupViewControllers(usingVCTypes)

这么一来,我们完全可以搭好框架,然后用 DSL 的方式进行配置,就可以在不触及 Swift 编码的情况下,很简单地完成一系列复杂操作了。

另外,在 Cocoa API 中我们也常遇到需要一个AnyClass的输入,这时候我们也应该使用.self的方式来获取所需要的元类型,例如在注册tableView的 cell 的类型的时候:

self.tableView.registerClass(UITableViewCell.self,forCellReuseIdentifier:"myCell")

.Type 表示的是某个类型的元类型,而在 Swift 中,除了class,struct和enum这三个类型外,我们还可以定义protocol。对于protocol来说,有时候我们也会想取得接口的元类型。这时我们可以在某个protocol的名字后面使用 .Protocol 来获取,使用的方法和 .Type 是类似的。


转载:swifter.tips/self-anyclass/

你可能感兴趣的:(swift 初探ANYCLASS,元类型和 .SELF)