首先我們先創造一個循環引用
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
http://www.cnblogs.com/MrTao/p/6824967.html
