Wil*_*Cat 35 memory closures ios swift
UIView.animateWithDuration(1,
animations: { [unowned self] in
self.box.center = self.boxTopRightPosition
},
completion: { [unowned self] completed in
self.box.hidden = true
})
Run Code Online (Sandbox Code Playgroud)
是否有必要避免内存泄漏?
Kir*_*ins 50
不,在这种情况下不需要.animations并且completion不会被保留,self因此不存在强保留周期的风险.
Pab*_* A. 30
嗯,"必要"与"推荐"不一样.如果您的问题是否有必要,那么@Kirsteins的回答很好,但是想象一下你想在一些工作之后在视图控制器中制作动画的情况,但你的视图控制器已经被释放(因为它不再在视图层次结构中了)或任何其他原因).在这种情况下,如果你不使用[weak self],你的视图控制器将在完成动画之前不会被释放,因为你将它保留在动画块中,但是保持它是有意义的是保持它直到动画不在再看一次?
所以,简单来说,在动画UIKit时你不需要使用weak自我引用,但是,如果它被释放你不需要保留你的视图,因为没有视图的动画没有意义,所以使用weak是一个不错的选择.
Tie*_*eme 13
不,不需要。正如柯斯坦斯所说:
不,在这种情况下不需要。动画和完成不是自己保留的,因此没有强大的保留周期的风险。
但是lhmgrassi说:
一旦取消分配,将调用反初始化程序,并且永远不会执行完成。
我不认为这是真的。完成模块将始终被调用。而且,如果您使用强大的自我,则在执行完成块之前,不会释放对象。
但是,如果使用[weak self],则完成块不会(临时)保留您的对象,并且可能会在触发完成块之前将其释放。完成块仍被触发,但self已经被触发nil。
如果[unowned self]在完成处理程序中使用,则在完成处理程序被调用之前,对象也可能被释放,这可能导致崩溃!
我已经举例说明了这一点。
小智 6
@Plabo,正如@Kirsteins所说,动画和完成不会被自己保留,所以即使你开始动画并且出于任何原因你的视图控制器已经被释放,它也会立即释放出来.所以,你不需要捕获'自我'.考虑以下愚蠢的例子:
class ViewController: UIViewController {
@IBOutlet weak var button : UIButton!
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad ViewController")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
UIView.animate(withDuration: 20, animations: {
self.button.frame = CGRect(x: 0, y: 300, width: 30, height: 30)
}) { finished in
self.button.frame = CGRect(x: 0, y: 100, width: 30, height: 30)
}
}
deinit {
print("deinit ViewController")
}
}
Run Code Online (Sandbox Code Playgroud)
一旦取消分配,将调用deinitializer并且永远不会执行完成.
恰好相反。您希望 self继续存在足够长的时间以便调用完成块。因此,self通过转义完成处理程序保持强大和保留是一件好事。
通常导致人们使用的担心weak self是保留周期。但这不是那样。保留周期是指当self保留保留的闭包时self,会导致泄漏,因为现在self永远无法释放。但这根本不是那样的情况。闭包因此self被保留,但不是被self! 所以暂时会有一些保留,但这是好的,而不是坏的。
| 归档时间: |
|
| 查看次数: |
8543 次 |
| 最近记录: |