
目录
一,访问控制
二,内存管理
三,指针
四,字面量
五,模式匹配
一,访问控制
1,访问级别
- 
open:允许在定义实体的模块、其他模块中访问,允许其他模块进行继承、重写(只能用在类、类成员上) - 
public:允许在定义实体的模块、其他模块中访问,不允许其他模块进行继承、重写 - 
internal:只允许在定义实体的模块中访问,不允许在其他模块中访问(默认权限) - 
fileprivate:只允许在定义实体的文件中访问 - 
private:只允许在定义实体的封闭声明中访问 
2,使用准则
- 一个实体不可以被更低访问级别的实体定义,比如:
 - 变量/常量类型
≥变量/常量 - 参数类型、返回值类型
≥函数 - 父类
≥子类 - 父协议
≥子协议 - 原类型
≥typealias - 原始值类型、关联值类型
≥枚举类型 - 定义类型A时用到的其他类型
≥类型A 



3,元组类型和泛型类型
- 元组类型的访问级别是所有成员类型最低的那个
 - 泛型类型的访问级别是
类型的访问级别以及所有泛型类型参数的访问级别中最低的那个 


4,成员和嵌套类型
- 类型的访问级别会影响成员(属性、方法、初始化器、下标)和嵌套类型的默认访问级别
 - 一般情况下,类型为
private或fileprivate,那么成员和嵌套类型默认也是private或fileprivate - 一般情况下,类型为
internal或public,那么成员和嵌套类型默认是internal - 直接在全局作用域下定义的
private等价于fileprivate 



5,成员重写
- 子类重写成员的访问级别
≥子类的访问级别或父类被重写成员的访问级别 - 父类的私有成员不能被作用域外定义的子类重写
 


6,setter和初始化器
- 
getter、setter默认自动接收它们所属环境的访问级别 - 可以给
setter单独设置一个比getter更低的访问级别,用以限制写的权限 - 如果想在另一个模块调用默认的无参初始化器,必须显式的将该初始化器设置为
public,因为默认是internal - 如果结构体有
private/fileprivate的存储实例属性,那么它的成员初始化器也是private/fileprivate - 
required初始化器的访问级别≥它的默认访问级别 



7,协议
- 协议中定义的会自动接收协议的访问级别,不能单独设置访问级别,
public协议中定义的也是public - 协议实现的访问级别
≥类型的访问级别或协议的访问级别 

8,扩展
- 如果有显式设置扩展的访问级别,扩展中添加的成员自动接收扩展的访问级别;如果没有显式设置,就会自动接收原本声明的访问级别
 - 不能给遵守协议的扩展显式设置访问级别
 - 在原本声明中声明的私有成员,可以在同一文件的所有扩展中访问它
 - 在扩展中声明的私有成员,可以在同一文件的原本声明和其他扩展中访问它
 


二,内存管理
1,基本概念
- 跟
OC一样,Swift也是采取基于引用计数的ARC内存管理方案(针对堆空间) - 强引用(
strong reference):默认情况下,所有的引用都是强引用 - 弱引用(
weak reference):通过weak来定义 
1>
weak只能修饰可选类型的var,因为实例销毁后,ARC会自动将弱引用设置为nil
2>ARC自动将弱引用设置nil时,不会触发属性观察器
- 无主引用(
unowned reference):通过unowned来定义 
1>类似于
OC中的unsafe_unretained,实例销毁后仍然存储着实例的内存地址
2>在实例销毁后访问无主引用,会产生运行时错误(野指针崩溃)

2,循环引用
- 
weak、unowned都能解决循环引用的问题,unowned比weak少一些性能消耗 - 在生命周期中可能会变为
nil的使用weak,初始化赋值后再也不会变为nil的使用unowned 



3,闭包
- 闭包表达式默认会对用到的外部对象产生强引用(对外部对象进行了
retain操作),这样容易引起循环引用问题 - 在闭包表达式的捕获列表中声明
weak或unowned引用,可以解决循环引用问题 - 如果想在定义闭包属性的同时引用
self,这个闭包必须是lazy的,因为在实例初始化完毕之后才能引用self - 如果
lazy属性是闭包调用的结果,就不用考虑循环引用问题,因为闭包调用后生命周期就结束了 



4,@escaping
- 非逃逸闭包、逃逸闭包一般都是当做参数传递给函数的
 - 非逃逸闭包:闭包调用发生在函数结束前,闭包调用在函数作用域内
 - 逃逸闭包:闭包有可能在函数结束后调用,闭包调用逃离了函数的作用域,需要用
@escaping来声明 - 逃逸闭包不可以捕获
inout参数 

5,内存访问冲突
- 内存访问冲突会在同时满足下列条件时发生:
 - 至少一个是写入操作
 - 访问的是同一块内存
 - 访问的时间重叠(比如在同一个函数内)
 

三,指针
1,基本概念
- 
Swift中也有专门的指针类型,这些都被定性为Unsafe(不安全的),常见的有以下4种类型: - 
UnsafePointer<Pointee>类似于const Pointee *(不可修改) - 
UnsafeMutablePointer<Pointee>类似于Pointee *(可修改) - 
UnsafeRawPointer类似于const void *(不可修改) - 
UnsafeMutableRawPointer类似于void *(可修改) 


2,获取指针
- 获取指向某个变量的指针
 

- 获取指向堆空间实例的指针
 

3,创建指针



4,指针转换
- 
unsafeBitCast是忽略数据类型的强制转换,不会因为数据类型的变化而改变原来的内存数据 

四,字面量
1,基本概念
- 下面代码中的
10、true、"Jack"就是字面量 
var age = 10
var isLike = true
var name = "Jack"
- 常见字面量的默认类型
 
public typealias BooleanLiteralType = Bool
public typealias IntegerLiteralType = Int
public typealias FloatLiteralType = Double
public typealias StringLiteralType = String
- 
Swift自带的绝大部分类型,都支持直接通过字面量进行初始化 
Bool、Int、Float、Double、String、Dictionary、Array、Set、Optional等
2,协议
- 
Swift自带类型之所以能够通过字面量初始化,是因为它们遵守了对应的协议 
Bool : ExpressibleByBooleanLiteral
Int : ExpressibleByIntegerLiteral
Float、Double : ExpressibleByIntegerLiteral、ExpressibleByFloatLiteral
String : ExpressibleByStringLiteral
Dictionary : ExpressibleByDictionaryLiteral
Array、Set : ExpressibleByArrayLiteral
Optional : ExpressibleByNilLiteral

3,应用



五,模式匹配
1,基本概念
- 什么是模式?
 
模式是用于匹配的规则,比如
switch的case、捕捉错误的catch、if/guard/while/for语句的条件等
- 有哪些模式?
 
通配符模式(
Wildcard Pattern)
标识符模式(Identifier Pattern)
值绑定模式(Value-Binding Pattern)
元组模式(Tuple Pattern)
枚举Case模式(Enumeration Case Pattern)
可选模式(Optional Pattern)
类型转换模式(Type-Casting Pattern)
表达式模式(Expression Pattern)
2,通配符模式
- 
_匹配任何值 - 
_?匹配非nil值 

3,标识符模式
- 给对应的变量、常量名赋值
 
var age = 10
let name = "Jack"
4,值绑定模式

5,元组模式

6,枚举Case模式
- 
if case语句等价于只有1个case的switch语句 


7,可选模式


8,类型转换模式

9,表达式模式

10,自定义表达式模式


