一、 基本操作
- 赋值运算 (=)
- 算术运算 (+)(-)(*)(/)
- 求余运算 (%)
- 一元运算 (+) (-)
- 复合赋值运算 (+=)
- 比较运算 (==) (!=) (>) (<) (>=) (<=)
(⚠️对于元组的比较运算,系统只提供少于7个元素的元组比较,若等于或大于7个元素,需自己实现) - 三元运算 ( ? : ) (if else)
- 空合运算 (Nil-Coalescing)( ?? )
- 区间运算
闭区间 (...)
左闭右开(..<)(..>) - 逻辑运算 (!) (&&) (||)
(Swift逻辑运算符&&和||是左关联, 复杂运算条件,建议使用括号)
二、字符串和字符
1.字符串 字面量
- 单行 ("abc")
- 多行 ( "" abc """)
- 转义字符 (\0) (\) (\t) (\n) (\r) ('') (') (\u{n})
- 区别于OC 中的(NSString/NSMutableString),swift 中的String 是值类型,值传递,通过copy,所以修改原值,不会改变传递后的值
2. 字符
-
字符类型,其值 只能包含一个字符
3.字符串操作
-
字符串拼接,修改
-
获取串中的字符
-
增加和删除
-
子串
子串和原串的内存关系⚠️
- 字符串比较 (==) (!=)
- 前缀和后缀 hasPrefix()/ hasSuffix()
- Unicode Representations of Strings ⚠️
4.字符串中的字符个数
-
swift中的字符是基于Unicode,OC是基于16-bitcode,所以,相同的串,在两种语言中计算出来的字符长度,可能不同
三、集合类型
1.Array
2.Sets
-
当一组数据中的元素顺序不重要,或者需要确定元素在数据组中唯一,
可以使用集合代替数组。
-
集合操作:交集/补集/合集等
-
子集/父集/ 绝对子集/绝对父集等
3.字典
四、控制流
1. for in
2. while
- while / repeat while (do while)
3. if else
4. switch (省略break)
-
Tuples
-
值绑定
-
where
-
混合类型
5. 控制转移 关键字
- continue
- break
- fallthrough
- return
- throw
⚠️Labeled Statements (贪吃蛇)
⚠️guard
五、Functions
func 函数名字(参数) -> 返回值 { }
- 参数标签
- 参数默认值
- 可变参数(一个函数最多有一个可变参数)
- inout修饰参数: 可改变地址 (不能修饰默认值参数和可变参数)
- 函数作为 一种数据类型
- 函数作为 函数的参数
- 函数作为 函数的返回值
- 嵌套函数
六、闭包
- 类似OC中的block
1.根据上下文推测出 参数 和 返回值
2.可省略 参数 和 返回值 的修饰形式
3.简写形式
4.尾部闭包 - 闭包可以 根据上下文 捕获值
- 闭包是引用类型
- @escaping
- @autoclosure
七、枚举
- swift 的枚举 不同于 OC的,不会被赋值为 一个默认的intger值
- 枚举是值类型,参与传值时,是被copy的
- 枚举里 可以包含方法
- enum case
- enum 与switch 结合
- 遍历枚举的case
- 相关值
- 原始值 可以是 字符/字符串/int/float,但每一个原始值必须是唯一;
如果为枚举中的第一个case赋值后,其后面的case值,系统会自动分配值;
若int类型的枚举 第一个case未被赋值,则默认从0开始 - 递归枚举 (indirect)
- 枚举可以遵守协议 ⚠️协议中的属性问题
八、结构体和类
共有,它们都可以:
1 通过定义属性 存储值
2 通过定义方法 实现功能
3 通过下标语法 获取它们内部的值
4 通过定义初始值 设置它们的初始状态
5 通过扩展 增加功能
6 遵守协议-
类 特有的:
1 通过继承,获取另一个类的特性
2 可以在运行时 检查类型转换
3 Deinitializers 允许一个类的实例释放塔分配的任何资源
4 引用计数 允许对一个类实例的多个引用
5 类是引用类型 (由于引用类型 多个变量可能关联同一个实例,所以可使用 === 和 !== 判断变量是否关联同一个实例)
-
结构体
1 结构体是值类型 ,参与传值时 是被copy的
⚠️指针
九、属性
1.计算属性,可用 类/结构体/枚举
2.存储属性,只能 类和结构体
3.懒存储属性,只能用var修饰
(如果多个线程同时访问了一个标记为lazy modifier的属性,并且该属性还没有初始化,那么不能保证该属性只初始化一次。)
- 存储属性 和 实例变量
5.计算属性 getter/ setter(optional) 方法
只读计算属性
6.属性观察者 (willSet/didSet):父类属性的willSet和didSet 在父类初始化器之后,子类初始化器中设置属性时被调用。当子类 在调用父初始化器之前 设置自己的属性时, 不会调用它们。
7.全局变量 和 局部变量
8.实例属性 和 类型属性(static/class) ⚠️
十、方法
- 实例方法
- self 属性 (一般不需要写明,除非参数名和属性名相同,此时,参数名优先)
- 结构体和枚举都是值类型,不允许修改实例方法中的属性,但是mutating 关键字可改变⚠️
- 突变方法 中的 self
- 类型方法 ( static/class 关键字)
十一、下标
- 关键字 subscript
- 下标在集合类型中的使用
- 下标可选值
十二、继承
- 一个类可以从另一个类 继承 方法/属性/下标/特性
- 基类
- 子类
- 重写(override):子类可覆盖父类的 实例方法/类型方法/实例属性/类型属性/下标/属性监听
- 标记为 (final)的上述特性,不能被重写
十三、初始化
init()
结构体类型的 成员逐一初始化
类的继承和初始化
-
类的指定构造器 和 便利构造器(关键字 convenience)
指定构造器和便利构造器的区别
1.一个指定构造器 必须调用其直接父类的指定构造器
2.便利构造器必须调用 本类的构造器
3.便利构造器最终调用的是 本类的指定构造器
初始化有两个阶段,四个安全检查
阶段一:
1.指定构造器和便利构造器 在类中被调用
2.类的新实例被分配内存,内存还未初始化
3.该类的指定构造器 确认该类引入的所有存储属性都有一个值,现在属性的内存被初始化了
4.指定构造器 交给 父类构造器 来执行自身存储属性的相同任务
5.这将继续沿着 类继承链进行,直到 到达链的顶部为止
6.一旦到达链的顶部,链中的最后一个类确保所有存储属性都有一个值,实例的内存就被认为是完全初始化了。阶段一完成
阶段二:
1.从链的顶部向下工作,链中的每一个指定构造器 都有进一步定制实例的选项。构造器现在可以访问self,可以修改self的属性,调用它的实例方法。
2.最后,链中的任何 便利构造器 都可以选择自定义实例,并与self一起工作。实例化 继承 和 重写
扩展
- 关键字 extension
- 与OC中的分类类似,但扩展没有名字
- 可以为已有的类/结构体/枚举/协议 添加 新功能。
- 可添加 计算型属性和计算型类型属性
不能 添加存储型属性,不能为已有属性添加属性观察期 - 可定义 实例方法和类型方法
1.若通过扩展添加一个新功能,则先前已有的实例也可用,即便它在扩展之前创建。
2.不能 重写已有的功能 - 可提供 新的构造器
扩展能为类添加新的便利构造器,但不能为类添加新的指定构造器或解析器。指定构再起和解析器,必须总是由原始的类提供(值类型中,特定条件下除外)。 - 可定义 下标
- 可定义和使用 新的嵌套类型
- 使一个已有类型 符合某种协议
协议
类/结构体/枚举 都可以遵守协议
- 协议语法
1.protocol SomeProtocol {}
2.遵守协议用冒号,遵守多个协议用逗号隔开
struct SomeStructure:FirstProtocol,AnotherProtocol {}
3.拥有父类的类 遵守协议时,父类名放在协议名之前,以逗号分隔
class SomeClass : SomeSuperClass, FirstProtocol, AnotherProtocol {} - 属性要求
- 方法要求
- Mutating 方法要求
- 构造器要求
不需要写花括号和构造器的实体 - 协议作为类型
- 委托(代理)模式
- 通过扩展添加协议一致性
- 通过扩展遵循协议
- 协议类型的集合
- 协议的继承
- 类类型专属协议
- 协议合成
- 检查协议一致性
- 可选的协议要求
- 协议扩展