Any、AnyObject
Any: 类似于OC中的instanceType,可以代表任意类型
AnyObject: 代表任意 类 类型,像枚举、结构体,都不行
is as
is:判断是否是某种类型(既可以是类与类之间的判断,也可以是类与协议之间的判断)
as:做类型强制转换
protocol testProtocol {}
class Animal {}
class Person: testProtocol, Animal {}
var p = Person()
print(p is Animal) // true
print(p is testProtocol) // true
ptint(p is Person) // true
var num: Any = 10;
print(num is Int) // true
X.self、X.Type、AnyClass
X.self: 是一个元类型(metadata)的指针,存放着类型相关的信息
x.self属于X.type类型
先来说下X.self :
class Person {}
var P = Person()
其内存分配如下:
image.png
还有一点在swift中不像OC一样需要继承一个通用的基类NSObject,在swift中如果不继承任何类的话,自己就是基类
Swift classes do not inherit from a universal base class. Classes you define without specifying a superclass automatically become base classes for you to build upon.” 摘录来自: Apple Inc. “The Swift Programming Language (Swift 5.0)。” Apple Books. https://books.apple.com/us/book/the-swift-programming-language-swift-5-0/id881256329
但是在swift中有个隐藏的基类,看如下代码:
class Person{}
// 输出:Optional(Swift._SwiftObject)
print(class_getSuperclass(Person.self))
可以看出就算没有继承任何类,他还是有父类的。所有的swift类都有个隐藏的基类:Swift._SwiftObject
Swift._SwiftObject文件在 swift源码可以找到:https://github.com/apple/swift/blob/master/stdlib/public/runtime/SwiftObject.h
大致搞懂了X.self是什么东西,再来说下X.Type
X.self 也是有自己的类型的,就是X.Type,就是元类型的类型
class Person {}
class Student : Person {}
var pType = Person.self // pType的类型就是Person.Type
var stuType: Studentp.Type = Student.self // stuType的类型就是 Studentp.Type
pType = Student.self // 因为子类,所有可以这样写
也可以定义一个接收任意类型的变量 AnyObject.Type
var anyType: AnyObject.Type = Perosn.self
anyType = Student.self
AnyClass:就是 AnyObject.Type的别名
public typealias AnyClass = AnyObject.Type
ok现在AnyObject 也搞清楚了
应用
这个东西有什么用呢?举个简单的例子
class Animal: NSObject {
// 必须是 required 保证子类调用init的时候初始化成功
required override init() {
super.init()
}
}
class Dog: Animal { }
class Cat: Animal { }
class Pig: Animal { }
func create(_ classes:[Animal.Type]) -> [Animal] {
var arr = [Animal]()
for cls in classes {
arr.append(cls.init())
}
return arr
}
create([Dog.self, Cat.self, Pig.self])
Self
1、Self代表当前类型
class Person {
var age = 10
static var count = 2
func test() {
print(self.age)
// 访问count的时候,一般通过类名直接访问
print(Person.count)
// 也可以使用 Self 访问
print(Self.count)
}
}
2、一般作为函数的返回值使用,限定返回值跟调用者必须类型一致
protocol Runable {
func test() -> Self
}
class Person : Runable {
required init() { }
func test() -> Self {
return type(of: self).init()
}
}
class Student: Person { }
let p = Person().test()
let s = Student().test()
// 输出:swift___闭包.Person
print(p)
// 输出:swift___闭包.Student
rint(s)
网友评论