Fat*_*tie 47 weak-references swift
我经常这样做,
let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
beep()
}
Run Code Online (Sandbox Code Playgroud)
在一个应用程序中,我们经常这样做
tickle.fresh(){
msg in
paint()
}
Run Code Online (Sandbox Code Playgroud)
但如果你做这个
let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
tickle.fresh(){
msg in
paint()
}
}
Run Code Online (Sandbox Code Playgroud)
当然,你必须做这个
let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) { [weak self] _ in
tickle.fresh(){
msg in
self?.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
或者,也许这个
let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) {
tickle.fresh(){
[weak self] msg in
self?.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
或许这个
let when = DispatchTime.now() + 2.0
DispatchQueue.main.asyncAfter(deadline: when) { [weak self] _ in
tickle.fresh(){
[weak self] msg in
self?.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
这三个建议似乎都很完美.这里意义的深度是什么?一个人应该做什么?强引用弱引用,弱引用还是强引用?生存还是毁灭?这就是问题所在!
Ham*_*ish 117
首先,请注意您通常不需要担心保留周期DispatchQueue.main.asyncAfter
,因为闭包将在某个时刻执行.因此,无论您是否弱捕获self
,您都不会创建永久保留周期(假设tickle.fresh
也没有).
是否[weak self]
在外部asyncAfter
闭包上放置捕获列表完全取决于是否要self
在调用闭包之前保留(在设置之后).如果self
在调用闭包之前你不需要保持活着[weak self]
,那么如果你这样做,请放入,然后不要放入.
你是否[weak self]
在一个内部封闭物(传递到内部封闭物上tickle.fresh
)取决于你是否已经self
在外部封闭物中被弱地捕获.如果还没有,那么你可以放置[weak self]
以防止内部封闭件保留它.然而,如果外部封闭件已经被弱地捕获self
,那么内部封闭件将已经具有弱的参考self
,因此[weak self]
增加到内部封闭件将不起作用.
所以,总结一下:
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
tickle.fresh { msg in
self.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
self
将由外封闭和内封闭保留.
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
tickle.fresh { msg in
self?.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
self
任何一个关闭都不会保留.
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
tickle.fresh { [weak self] msg in
self?.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
与上述相同,[weak self]
内部封闭件的附加物没有效果,因为self
外部封闭件已经很弱地捕获.
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
tickle.fresh { [weak self] msg in
self?.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
self
将由外封闭件保留,但不由内封闭件保留.
当然,可能是您不希望self
被外部闭合保留,但您确实希望它由内部闭合保留.在这种情况下,您可以在外部闭包中声明一个局部变量,以便self
在您可以在内部闭包中捕获时保持强引用:
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
guard let strongSelf = self else { return }
tickle.fresh { msg in
strongSelf.paint()
}
}
Run Code Online (Sandbox Code Playgroud)
现在,self
外封闭不会保持活着,但一旦它被调用,如果self
仍然存在,它将由内封闭保持活着,直到该封闭被解除分配.
回应:
强引用弱引用,弱引用还是强引用?
弱引用实现为选项,它们是值类型.因此,您无法直接对其进行强引用 - 而是首先必须打开它,然后对底层实例进行强引用.在这种情况下,你只是处理一个强引用(完全像我上面的例子strongSelf
).
但是,如果一个弱引用被加框(这会发生在闭包捕获中 - 值类型将被放入堆分配的框中) - 那么你确实可以对该框有一个强引用.这种效果相当于对原始实例的弱引用,你只需要一个不可见的额外间接位.
事实上,这正是在外部闭合弱捕获self
并且内部闭合"强烈捕获"弱参考的示例中发生的情况.结果是两个闭合都没有保留self
.
归档时间: |
|
查看次数: |
16552 次 |
最近记录: |