一、self和Self
1、self出现在对象方法中,self就代表对象。self出现在类方法中,就代表类。
2、Self代表当前的类型,Self一般用作返回值类型,限定返回值跟方法调用者必须是同一类型(也可以作为参数类型)。
- self调用类中的属性。
class Person {
var age = 1
static var count = 2
func run() {
print(self.age) // 1
print(Self.count) // 2
}
}
- 创建协议方法,返回Self,再创建两个类Person、Student,调用协议方法,返回的是当前的类型Person、Student。如下:
protocol Runnable {
func test() -> Self
}
class Person : Runnable {
required init() {}
func test() -> Self {
type(of: self).init()
}
}
//Student继承Person,同时也继承了代理,可以直接调用方法。
class Student : Person {}
var p = Person()
print(p.test()) // Person
var stu = Student()
print(stu.test()) // Student
}
二、Any&AnyObject
Swift提供了两种特殊类型:
- Any代表任意类型(类、枚举、结构体,也包括函数类型)
- AnyObject代表任意
类
类型(在协议后面写上AnyObject,只能代表只有类能遵守这个协议)
在协议后面写上class,也表示只有类能遵守这个协议
var stu : Any = 10
var stuArr = [Any]()
var dicMessage = [String:Any]()
stu = "zhangkai"
dicMessage = ["name":"zhangkai","age":28,"sex": "man"]
stuArr.append(1)
stuArr.append(3.14)
stuArr.append("Jack Ma")
stuArr.append({ 10 })
stuArr.append(dicMessage)
let dic = stuArr[3]
print("~~~~~~~~~~~strArr:",stuArr,dic)
三、X.self、X.Type、AnyClass
- X.self是一个元类型(metadata)的指针,metadata存放着类型相关信息。
- X.self是X.Type类型。
四、CaseIterable
让枚举遵守CaseIterable协议,可以实现遍历枚举值。
enum Seasons : CaseIterable {
case Spring,Summer,Autumn,Winter
}
let seasons = Seasons.allCases
print(seasons)
for season in seasons {
print("~~~~~~~~~season:",season)
}
结果:
[TestAbc.Seasons.Spring, TestAbc.Seasons.Summer, TestAbc.Seasons.Autumn, TestAbc.Seasons.Winter]
~~~~~~~~~season: Spring
~~~~~~~~~season: Summer
~~~~~~~~~season: Autumn
~~~~~~~~~season: Winter
五、mutating
只有将协议中的实例方法标记为mutating
:
- 才允许结构体、枚举的具体实现修改自身内存。
- 类在实现方法时不用加
mutating
,枚举、结构体才需要加mutating
。
protocol Drawable {
mutating func draw()
}
class size: Drawable {
var width:Int = 3
func draw() {
width = 10
}
}
struct Point : Drawable {
var width:Int = 3
mutating func draw() {
width = 10
}
}
如果struct中不写mutating,那么会提示Cannot assign to property: 'self' is immutable
- 注释:
immutable:不可变的 mutable:可变的
六、init
- 协议中还可以定义初始化器。
在非final类实现时必须加上required。
protocol Drawable {
init(x:Int,y:Int)
}
class Point : Drawable {
required init(x: Int, y: Int) {}
}
final class Size : Drawable{
init(x: Int, y: Int) {}
}
- 如果从协议实现了初始化器,刚好是实现了父类指定的初始化器。
那么这个初始化器必须同时添加required、override。
protocol Liveable {
init(age : Int)
}
class Person {
init(age : Int) {}
}
class Student: Person,Liveable {
required override init(age: Int) {
super.init(age: age)
}
}