我们都知道weak 关键字可以解决内存不释放问题,但是使用上有些讲究。
看代码:
import UIKit var str = "Hello, playground" class Name{ deinit { print("name deinit") } } class Person{ var name:Name? func test(){ let tempName = Name() weak var weakName = tempName self.name = weakName } } let person = Person() person.test()
运行之后,控制台并没有输出name deinit,也就是说 Name对象并没有被释放。
再看下这段代码:
import UIKit var str = "Hello, playground" class Name{ deinit { print("name deinit") } } class Person{ weak var name:Name? func test(){ let tempName = Name() self.name = tempName } } let person = Person() person.test()
运行后,输出了name deinit.
从这上面两个对比中,我们可以看出 weak 声明的指针,当被当做右值时,所代表的也是对象的地址,和strong型的指针没有区别。
把一个weak的指针再赋给一个strong型的指针,这个stong型的指针就会把相应对象进行强引用。
看一个实际问题:下面这段代码就是错误的! 我们在写block时,常常记得使用
weak var weakSelf = self 声明一个变量,之后在block中使用weakSelf 来防止循环引用。这种做法好用的原因,是因为我们自己实现的block中,不会把weakself当做右值对一个强指针进行赋值。而 timer的默认实现里,我认为是有这种赋值的,从而导致了循环引用。
class PlayerScene: SKScene { var lockedTimer:Timer! required init?(coder aDecoder: NSCoder) { weak var weakSelf = self //错误写法 lockedTileNodeTimer = Timer(timeInterval: 1.0, target: weakSelf, selector: #selector(checkLockedTileNodes), userInfo: nil, repeats: true) }