1. weak 不是万能的
class A: NSObject {
var b: B?
deinit {
print("A died")
}
}
class B: NSObject {
var aa: A?
func setA(a: A?) {
if let a = a {
aa = a
}
}
}
var b: B! = B()
var a: A? = A()
weak var aa = a
b.setA(a: aa)
a?.b = b
a = nil // A 的 deinit 没走
b.aa = nil // A 的 deinit 走了
上面的例子说明:__strong 不是瞎用的,避免循环引用,从根源做起。 let a = a相当于__strong。可以短暂在一个scope{}中强引用,不要持续持有,否则同样造成,循环引用。
2. 全局变量和单例的使用
这两个使用起来,很大的方便了代码,但一定要注意不要持有不该持有的对象,避免造成不释放。
3. weak 在闭包中的顺序很重要
class ClassA: NSObject {
var closure: (() -> ())?
}
class ClassB: NSObject {
var closure: (() -> ())?
}
class A: NSObject {
var a = ClassA()
override init() {
super.init()
a.closure = {
[weak self] in
let b = ClassB()
b.closure = {
print(self?.description ?? "??????")
}
}
}
deinit {
print("A has died!")
}
}
var a: A? = A()
a = nil // A 的 deinit 没走
class ClassA: NSObject {
var closure: (() -> ())?
}
class ClassB: NSObject {
var closure: (() -> ())?
}
class A: NSObject {
var a = ClassA()
override init() {
super.init()
a.closure = {
let b = ClassB()
b.closure = {
[weak self] in
print(self?.description ?? "??????")
}
}
}
deinit {
print("A has died!")
}
}
var a: A? = A()
a = nil // A 的 deinit 走了
上面两段代码就一句[weak self] in位置不一样, 但第一段的造成了循环引用,虽然在 b.closure 中使用 weak 来修饰,但由于 b.closure 也在 a.closure 中,所以a.closure 优先持有 self, 造成循环引用。第二段 b.closure 引用的是 a.closure中的weak self, 所以不会造成循环引用。
4. 关于 SnapKit ConstraintMakerEditable constraint 的循环引用
var centerConstraint: ConstraintMakerEditable?
centerConstraint = make.centerX.equalTo(target)
var centerConstraint: Constraint?
centerConstraint = make.centerX.equalTo(target).constraint
ConstraintMakerFinalizable 是ConstraintMakerEditable的父类。
通过查看 SnapKit 源码,发现make.centerX.equalTo(target)返回的是ConstraintMakerFinalizable, 然而 internal let description: ConstraintDescription 是 ConstraintMakerFinalizable的一个属性,ConstraintDescription 又持有 Self, 当Self强持有ConstraintMakerFinalizable时,造成循环引用,而ConstraintMakerFinalizable 的 constraint返回的是internal let description: ConstraintDescription的constraint属性,Self和internal let description: ConstraintDescription同时持有internal let description: ConstraintDescription的constraint属性,不会造成循环引用。









网友评论