1.访问控制
- open:允许在定义实体的模块、其他模块中访问,允许其他模块进行继承、重写
- public:允许在定义实体的模块、其他模块中访问,不允许其他模块进行继承、重写
- internal:只允许在定义实体的模块中访问,不允许在其他模块中访问
- fileprivate:只允许在定义实体的源文件中访问
- private:只允许在定义实体的封闭声明中访问
2.使用准则
一个实体不可以被更低访问级别的实体定义。一般情况下,类型为private或fileprivate,那么成员\嵌套类型默认也是private或fileprivate ,类型为internal或public,那么成员\嵌套类型默认是internal。
3.内存管理
OC一样,Swift也是采取基于引用计数的ARC内存管理。
Swift的ARC中有3种引用:
- strong ,强引用,默认也是强引用。
- weak ,弱引用,必须是可选类型的var,因为实例销毁后,ARC会自动将弱引用设置为nil
- unowned ,无主引用,不会产生强引用,实例销毁后仍然存储着实例的内存地址。
4.weak和unowned限制
只能使用在类实例上面
class Person {}
weak var p: Person?
unowned var p1: Person?5.循环引用
weak、unowned 都能解决循环引用的问题,unowned 要比weak 少一些性能消耗。
在生命周期中可能会变为 nil 的使用 weak。
初始化赋值后再也不会变为 nil 的使用 unowned。
6.闭包的循环引用
可以lazy属性是闭包的调用的结果,则不用考虑循环引用问题。
class Person {
var age: Int = 0
lazy var getAge: Int = {
self.age
}()
deinit { print("deinit") }
}7.逃逸闭包
非逃逸闭包、逃逸闭包,一般都是当做参数传递给函数。
非逃逸闭包:闭包调用发生在函数结束前,闭包调用在函数作用域内。
逃逸闭包:闭包有可能在函数结束后调用,闭包调用逃离了函数的作用域,需要通过@escaping声明。
typealias Fn = () -> ()
func test1(_ fn: Fn) {
fn()
}
var gFn: Fn?
func test2(_ fn: @escaping Fn){
gFn = fn
}8.内存访问冲突
内存访问冲突会在两个访问满足下列条件时发生:
- 至少一个是写入操作
- 它们访问的是同一块内存
- 它们的访问时间重叠(比如在同一个函数内)
例子:
//不存在冲突
func plus(_ num: inout Int) -> Int {
num + 1
}
var number = 1
number = plus(&number)
//存在访问冲突
func plus1(_ num: inout Int){
return num += number
}
plus1(&number)
//解决冲突
var otherNumber = number
plus1(&otherNumber)
number = otherNumber