这是我的自定义视图:
class CustomVIew: UIView {
deinit {
print("custom view deinit")
}
var onTapViewHandler: (()->Void)?
}
和视图控制器:
class ViewControllerB: UIViewController {
var customView: CustomVIew!
deinit {
print("B deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
let customView = CustomVIew()
customView.onTapViewHandler = { [unowned self] in
self.didTapBlue()
}
customView.frame = CGRect(x: 50, y: 250, width: 200, height: 100)
customView.backgroundColor = UIColor.blueColor()
view.addSubview(customView)
self.customView = customView
}
func didTapBlue() {
}
}
当从导航堆栈中弹出控制器时,一切都很好:
B deinit
custom view deinit
但是当我替换这段代码时:
customView.onTapViewHandler = { [unowned self] in
self.didTapBlue()
}
用这个:
customView.onTapViewHandler = didTapBlue
然后,控制台上没有打印任何内容。 CustomView和ViewController没有发布,为什么?
为什么customView.onTapViewHandler = didTapBlue
会抓取对self
的引用?
答案 0 :(得分:6)
Swift函数是一种闭包。所以像闭包(目标c中的块)函数可以捕获引用。
当classLibrary.classes.shift
执行时,对customView.onTapViewHandler = didTapBlue
的引用即self
引用在这种情况下将被函数调用捕获。
同一时间ViewControllerB
的视图强烈引用ViewControllerB
,因此它会保留周期。
关于使用CustomVIew
,Apple document说:
弱引用和无主引用在引用周期中启用一个实例 引用另一个实例而不保持强势。 然后,实例可以在不创建强大的情况下相互引用 参考周期。
这意味着没有循环引用和保留循环。