首先我们先创造一个循环引用
var nameB:(()->())? override func viewDidLoad() { super.viewDidLoad() let bu = UIButton(type: .ContactAdd) bu.addTarget(self, action: "tap", forControlEvents: .TouchUpInside) view.addSubview(bu) run { print("name") self.view.backgroundColor = UIColor.greenColor() } } func tap() { print("tap") dismissViewControllerAnimated(true) { () -> Void in print("dismissViewControllerAnimated") } } func run(name: ()->()) { print("执行代码") nameB = name name() } deinit { print("deinit") }
在代码中我们创建一个全局变量nameB, 然后我们在调用方法run的时候传入一个闭包, 在闭包里面我们用self.view...这样, 这包闭包就引用了self,
然后我们又在run 里面赋值给nameB这样就导致了, 这样控制器self又引用闭包, 所以就造成了循环引用
可以执行一下上面代码肯定不会走deint方法
要解决闭包的循环引用其实也不难, 我们在oc中解决循环引用使用weak修饰一个self, 在swift中也一样
weak var weakSelf = self
但要注意这里的weakSelf 就被包装成<optional>类型了, 所以在用的时候要强制解析
class viewController2: UIViewController { var nameB:(()->())? override func viewDidLoad() { super.viewDidLoad() let bu = UIButton(type: .ContactAdd) bu.addTarget(self, action: "tap", forControlEvents: .TouchUpInside) view.addSubview(bu) weak var weakSelf = self run { print("name") weakSelf!.view.backgroundColor = UIColor.greenColor() } } func tap() { print("tap") dismissViewControllerAnimated(true) { () -> Void in print("dismissViewControllerAnimated") } } func run(name: ()->()) { print("执行代码") nameB = name name() } deinit { print("deinit") } }
这样就肯定会进deinit方法
其实闭包跟block很像, 如果想详细的了解block思想可以看看我总结的这个blog