【问题标题】:Is unowned logically equivalent to weak! in Swift无主逻辑上等价于弱!在斯威夫特
【发布时间】:2014-09-16 10:28:52
【问题描述】:

这些块在相同的情况下是否总是失败(当闭包正在执行但 self 被释放时)?

{ [unowned self] in
    //use self
    self.number = self.number + 1
}

{ [weak self] in
    //use self!
    self!.number = self!.number + 1
}

【问题讨论】:

  • 你的意思是你在执行这段代码时崩溃了?
  • 是的,如果 self 已被释放。我在问两个块在逻辑上是否总是表现相同?

标签: ios xcode swift automatic-ref-counting


【解决方案1】:

无主引用不保持对自身的强引用,但它假设对象总是有一些值(不是零),如果在执行块时自我解除分配,上面的代码会崩溃。

对于弱的情况,如您的示例所示,弱是块内的可选类型,因此也可能有一个值,也可能是零。您有责任检查该值是否存在并在其上调用方法。如上所述,如果您使用展开运算符 (!),当 self 已被释放时,它肯定会崩溃。因此,两个版本的代码都会崩溃,如果它发生在块仍在执行并且同时 self 被释放的情况下。

所以,我建议使用可选检查来保护此类崩溃,

{ [weak self] in
    if let me = self {
       me.number = me.number + 1
    }
}

【讨论】:

  • “如果,在执行块时如何自我释放”或在块执行之前
【解决方案2】:

是的,它们是等价的。这就是unowned 的重点——它就像weak,只是你不必处理一个可选项并解包它,因为它的类型是解包的非可选类型; weak 在每次出现时总是被强制解开。

【讨论】:

  • 虽然unowned 是不安全的——如果self 被释放,它会崩溃。
  • @AaronBrager:没有比强制展开更“不安全”的了。问题是它们是否相同。如果它是weak,并且对象被释放,则值将是nil。并且强制解包具有值 nil 的可选项将崩溃。
【解决方案3】:

应该这样使用

{ [weak self] in

    guard let weakSelf = self else {
       return 
    }

    weakSelf.number = weakSelf.number + 1
}

感谢 @José 的评论,请注意,尽管以下代码目前可以工作,但它被认为是编译器错误,应该避免 https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007425.html

你也可以像这样解开self

{ [weak self] in

    guard let `self` = self else {
       return 
    }

    // Now you can use `self` safely
    self.number = self.number + 1
}

【讨论】:

猜你喜欢
  • 2014-08-02
  • 2022-01-21
  • 2017-07-22
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-08
  • 2017-11-13
相关资源
最近更新 更多