繁体   English   中英

为什么[弱自我]工作但是[无主自我]在Swift闭包中中断?

[英]Why does [weak self] work but [unowned self] break in a Swift closure?

通过完成闭包调用自身来重复此SpriteKit操作。 它使用闭包,而不是SKAction.repeatActionForever() ,因为它需要每次重复生成一个随机变量:

class Twinkler: SKSpriteNode {
  init() {
    super.init(texture:nil, color:UIColor.whiteColor(), size:CGSize(width:10.0, height:10.0))
    twinkle()
  }
  func twinkle() {
      let rand0to1 = CGFloat(arc4random()) / CGFloat(UINT32_MAX)
      let action = SKAction.fadeAlphaTo(rand0to1, duration:0.1)
      let closure = {self.twinkle()}
      runAction(action, completion:closure)
  }
}

我想我应该使用[unowned self]来避免与闭包的强引用循环。 当我这样做时:

let closure = {[unowned self] in self.twinkle()}

它崩溃了错误: _swift_abortRetainUnowned 但如果我使用[weak self]代替:

let closure = {[weak self] in self!.twinkle()}

它执行没有错误。 为什么[weak self]工作但[unowned self]破裂? 我应该在这里使用其中任何一种吗?

Twinkler对象在程序的其他地方被强烈引用,作为另一个节点的子对象。 所以我不明白[unowned self]引用是如何破坏的。 它不应该被解除分配。

我尝试使用dispatch_after()在SpriteKit外部复制此问题,但我无法做到。

如果封闭使用自我可能是零[弱自我]

如果自我永远不会在闭包中使用[无主自我]

如果你在使用[无主自我]时崩溃,那么在封闭的某个时刻self可能是零,所以你需要使用[弱自我]

文档中的示例非常适合在闭包中使用strongweakunowned

https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html

这听起来像个错误。 {[unowned self] in self.twinkle()}中的{[weak self] in self!.twinkle()} {[unowned self] in self.twinkle()}应该与{[weak self] in self!.twinkle()}

我最近遇到了类似的崩溃。 在我的情况下,有时新对象的初始化恰好与解除分配的对象具有完全相同的内存地址。 但是,如果两个对象具有不同的内存地址,则代码将执行得很好。

所以这是我疯狂的解释。 当swift将强引用置于闭包并检查其捕获列表时,如果捕获列表中的变量显示为“unowned”,它将检查对象是否已被释放。 如果对象被标记为“弱”,它不会检查。

由于保证对象在闭包中永远不会是零,因此它实际上永远不会崩溃。

所以,可能是语言错误。 我对此的看法是使用弱而不是无主。

为了不出错,它应该是:

let closure = {[weak self] in self?.twinkle()}

let closure = {[weak self] in self!.twinkle()}

力量解开后的感叹号会在nil上引发错误。 如果self为零,就像强行展开一样,无主将抛出错误。 在执行这两个选项中的任何一个时,您应该使用和guard或if语句来保护nil。

这只是我对文档的阅读,但这是一个理论。

与弱引用一样, 无主引用并不会强烈保留它所引用的实例。 然而,与弱引用不同,假定无主引用始终具有值。 因此,无主引用始终定义为非可选类型。 [ 来源 ]

你说Twinkler对象被强烈引用为另一个节点的子节点,但SKNode的子节点是隐式解包的选项。 我敢打赌,问题不在于self被释放,而是当你试图创建闭包时,Swift正在创建一个对可选变量的无主引用。 因此, [weak self]是这里使用的右关闭捕获列表。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM