简体   繁体   English

在 swift 关闭中使用 `[weak self]` 是正确的方法吗?

[英]Is it the right way using `[weak self]` in swift closure?

I always using [weak self] in swift closure to prevent reference cycle.我总是在快速关闭中使用[weak self]来防止引用循环。 Here is the code below, is it the correct way?这是下面的代码,这是正确的方法吗?

someTask(completion: {[weak self] (result) in
        if self == nil {  
            return
        }

        //is it safe when reach here? 

        self!.xxx = yyy
        self!.doLongTermWork()
        self!.finish()  //will crash when self is nil?
    })

Weak self does not keep a strong hold on the instance.弱自我不会对实例保持强大的控制。 So when self.doLongTermWork() , will self be set to nil again somewhere else?那么当self.doLongTermWork()self会在其他地方再次设置为nil吗?

Your pattern has race condition.你的模式有竞争条件。 If self was deallocated at the exact same time as your completion handler closure was executing, it could crash.如果self在执行完成处理程序闭包的同时被释放,它可能会崩溃。 As a general rule, avoid using the !作为一般规则,避免使用! forced unwrapping operator if you can.如果可以,强制解包运算符。

  1. I'd lean towards the guard “early exit” pattern (reducing nested braces, making code easier to read).我倾向于guard “提前退出”模式(减少嵌套大括号,使代码更易于阅读)。 The standard Swift 4.2 solution is:标准的 Swift 4.2 解决方案是:

     someTask { [weak self] result in guard let self = self else { return } self.xxx = yyy self.doLongTermWork() self.finish() }
  2. Before Swift 4.2, which implemented SE-0079 , we would have to do something like:在实现SE-0079 的Swift 4.2 之前,我们必须执行以下操作:

     someTask { [weak self] result in guard let strongSelf = self else { return } strongSelf.xxx = yyy strongSelf.doLongTermWork() strongSelf.finish() }

    You can see why we prefer the Swift 4.2 improvement, as this strongSelf syntax is inelegant.您可以strongSelf为什么我们更喜欢 Swift 4.2 的改进,因为这种strongSelf语法不雅。

  3. The other obvious alternative is just:另一个明显的选择是:

     someTask { [weak self] result in self?.xxx = yyy self?.doLongTermWork() self?.finish() }

    Sometimes you need the “weak self - strong self dance” (the first two alternatives), but it would not appear to be the case here.有时您需要“弱自强自舞”(前两种选择),但这里似乎并非如此。 This is likely sufficient.这可能就足够了。

There are other scenarios/edge cases that one might contemplate, but these are the basic approaches.人们可能会考虑其他场景/边缘情况,但这些是基本方法。

You said:你说:

someTask(completion: {[weak self] (result) in
    if self == nil {  
        return
    }
    //is it safe when reach here? 
    self!.xxx = yyy
})

No!不! You have not retained self , so in theory it might become nil at any time during the execution of the closure.你没有保留self ,所以理论上它可能会在闭包执行期间的任何时候变为nil It probably won't, but "probably" is not good enough.它可能不会,但“可能”还不够好。 And exclamation marks are always an invitation to crash.并且感叹号总是一个崩溃的邀请。

Do the weak-strong dance, and do it correctly:做弱强舞,并正确地做:

someTask(completion: {[weak self] (result) in
    if let self = self {  // or let `self` before Swift 4
        // here, self is safe, because you made the reference strong again
        self.xxx = yyy
    }
})

You can use it like this from Swift 4.2你可以从 Swift 4.2 像这样使用它

someTask(completion: {[weak self] (result) in
    guard let self = self { return }

    //it safe when reach here always

    self.xxx = yyy
    self.doLongTermWork()
    self.finish()
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Swift闭包中使用[弱自我]和赋值 - Using [weak self] and assignment in Swift closure 快速关闭中gcd的自我弱化 - weak self in gcd in swift closure Swift [weak self] 用于在嵌套闭包中在 main 上调度 - Swift [weak self] for Dispatching on main in a nested closure 如何将 [弱自我] 应用于 swift function(不关闭) - How to apply [weak self] to a swift function (not closure) 使用目标c中的swift定义的闭包时弱的自我与自我 - Weak self vs self when using closure defined in swift in objective c 为什么[弱自我]工作但是[无主自我]在Swift闭包中中断? - Why does [weak self] work but [unowned self] break in a Swift closure? 使用带有闭包的TableViewCell委托函数时使用[弱自我]的安全方法? - Safety way to use [weak self] when using TableViewCell delegate function with closure? Swift 闭合中的“弱自我”等效的 Objective-C 是什么? - What is the Objective-C equivalent of 'weak self' in a Swift closure? 将 function 与闭包“弱自我”作为 swift 中的参数传递 - Passing a function vs a closure “weak self” as parameter in swift 在 Swift 中,如果我有一个捕获 [weak self] 的闭包,在闭包的开头解开可选的 self 是一种好习惯吗? - In Swift, if I have a closure capturing [weak self], is it good practice to unwrap the optional self at the beginning of the closure?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM