1.Swift简介
Swift是在Objective-C的基础上,借鉴了很多现代高级语言,发展而成的一门安全、高效、支持多种编程规范式的编程语言。
苹果在2014年6月WWDC上推出1.0版本。
于2015年6月WWDC推出2.0版本。
2015年12月4日,苹果公司宣布Swift开放源代码。
Swift之父:Chris Lattner
2.值类型与引用类型
类型成员
属性 property 数据成员 data member,描述对象状态
方法 method 函数成员 function member,描述对象行为
初始化器 init
析构器 deinit
下标 subscript
拷贝行为
传参行为
堆栈比较
3.类型成员:属性
属性表达实例状态或类型状态。
属性类别:存储属性,计算属性。
可变性:变量属性,常量属性。
归属权:实例属性,类型属性(静态属性)。
存储属性的本质:一个存储变量;两个访问器方法:get与set
计算属性:两个访问器方法:get与set;可以简化为get
存储属性的内存模型
引用存储属性的内存模型
存储属性的生存周期
实例存储属性跟随实例存储(值类型在栈上,引用类型在堆上),生存周期跟随实例
静态存储属性(无论值类型或引用类型)的值存储在静态数据区,生存周期从类型加载开始,到类型卸载结束
值存储属性直接“内嵌”在实例中
引用存储属性通过指针“强引用”堆上的引用类型实例,ARC针对强引用进行计数管理。
更多属性功能
lazy存储属性:延迟初值计算到访问时
属性初始化:默认值 或者构造器初始化
属性观察者:检测改变。willSet在改变前调用 didSet在改变后调用
4.类型成员:方法
函数:代码段上的可执行指令序列。
全局函数和成员函数。
方法是类型的成员函数,表达行为,方法可以定义于以下类型:
class 、 struct 、 enum
归属权:
实例方法:实力行为,可以访问实例方法与属性、以及类型属性与方法。
类型方法:类型行为,只能访问类型属性与方法。
方法参数
fun(参数1,参数2...)->返回值{ }
参数形式:外部参数名 本地参数名:类型
声明时可以省略外部参数名,这时外部参数名使用本地参数名。
调用时,第一个参数名可忽略,但后面的参数名必须显式表明。如果在声明时加 _,调用时也可以忽略参数名。
方法可以没有参数,也可以没有返回值
参数传递默认为传值方式
5.类型成员:初始化器
初始化器用于初始化类型实例,是一个特殊的函数,无返回值。
类型实例的初始化过程:1.分配内存,2.调用初始化器初始化内存。
初始化可以定义于以下类型:class、struct、enum
归属权:只有实例初始化器,没有类型初始化器。
初始化实例属性
初始化器主要用于初始化实例存储属性,两种初始化形式:指定默认值、自定义初始化器
所有存储属性必须被初始化
实例存储属性或者指定默认值,或者在初始化器内初始化
类型存储属性必须指定默认值(因为没有类型初始化器)
可选属性类型可以不初始化
存储属性被初始化时,不会调用属性观察者
默认初始化器
一个类可以有多个初始化器,但至少需要一个初始化器。
如果一个类没有提供初始化器,那么编译器会自动生成一个默认初始化器。
默认初始化器,无参形式 init()
使用swiftc生成sil文件,观察编译器自动生成代码。
指定初始化器VS.便捷初始化器
指定初始化器(Designated Initializer)为类的主初始化器,负责初始化所有属性。必须调用其父类的主初始化器。
便捷初始化器(Convenience Initializer)为类的辅助初始化器。必须调用同类的指定初始化器。
6.类型成员:析构器
析构器(deinit)在实例内存被释放前调用,用于释放实例使用的非内存资源。
析构器仅可以定义于class,且只能定义一个。struct和enum不能定义析构器。
归属权:只有实例析构器,没有类型析构器。
析构器由运行时根据ARC的释放规则,自动调用,程序员无法手工调用。
ARC,全称Automatic Reference Counting 自动引用计数,用于管理堆上的对象实例所分配的动态内存。
ARC不负责管理栈上的内存。栈上的内存由运行时根据函数生存周期来自动管理栈的创建和销毁。
ARC通过追踪“对象被引用的计数”来确定对象是否还需要被访问。如果对象的引用计数为0,ARC会立即调用析构器,并随后释放对象内存。
引用计数管理
对象引用计数增1:
新创建对象并赋值给变量,引用计数加1;
将对象引用拷贝给其他变量或常量;
将对象赋值给其他属性(无论实例属性,还是类型属性);
将对象传递给函数参数(非inout参数),或者返回值。
对象引用计数减1:
将变量赋值为nil;
将属性赋值为nil,或者属性所在的对象被释放(实例属性);
传值参数离开函数。
引用计数变为0时,析构器被调用,内存释放。
7.下标与操作符
下标 Subscripts
下标支持使用索引的方式访问“集合式”实例,例如vector[index]。
下标可以定义的类型:class、struct、enum。
下标可以类比为“含参的计算属性”,其本质是一对带索引参数的访问器方法(get/set)。
访问下标
归属权:只能定义实例下标,不能定义类型下标(静态下标)。
可以定义读写下标(get/set),或者制度下标(get)。
下标的索引参数可以是任意类型,也可以设计多个参数。
一个类型可以提供多个下标的重载版本(参数不同)。
标准操作符
赋值操作符:= 不返回结果
算术操作符:+ - * / %检测溢出错误
自增、自减操作符: ++ --
复合赋值操作符:+= -=
比较操作符:> < >= <=
逻辑操作符:&& || !
位操作符:~ & | ^ << >>
三元操作符:a?b:c
范围操作符:a..<b a...b
值相等:== !=
引用相等:=== !==
重载操作符
除了标准操作符之外,还可以针对自定义类型重载标准操作符。重载操作符又称“操作符函数”,其本质是全局函数。
可以重载前缀(prefix)、中缀(infix)、后缀(postfix)操作符。前缀和后缀操作符需要加关键词:prefix或postfix。
也可以通过将参数设置为inout参数,重载复合赋值操作符,例如 +=,-=。
除了重载Swift标准操作符,也可以自定义新的操作符,并重载。
相等操作符
引用相等
判断对象地址是否相等,仅针对引用类型,不适用于值类型;
相等操作符===
不等操作符!==
值相等
判断实例值是否相等,自定义类型需重载提供“值比较语义”;
相等操作符 ==
不等操作符!=