gpt4 book ai didi

swift - 异步函数调用与无主对象的取消初始化发生冲突

转载 作者:行者123 更新时间:2023-11-30 12:17:05 24 4
gpt4 key购买 nike

我有与此类似的代码,与异步上下文中的事件处理相关:

class A {
var foos: Set<Fooable>
}

protocol Fooable {
func bar()
}

class B {
var a: A
var foo: Foo!

init(a: A) {
self.a = a
}

func start() {
self.foo = Foo(self)
self.a.foos.insert(self.foo)
}

deinit {
<... *>
if self.foo != nil {
self.a.remove(self.foo)
}
}


class Foo: Fooable {
unowned let b: B

init(_ b: B) {
self.b = B
}

func bar() { <... #> }
}
}

我认为这应该是安全的代码:在 b 的实例之前消失了,它会清除所有对其 foo 的引用,所以引用Foo.b永远不应该成为问题。

但是,我从 self.b 的访问中收到此错误Foo.bar()里面(在一些 GCD 队列上运行,而不是在主队列上运行):

exc_breakpoint (code=exc_i386_bpt subcode=0x0)

调试器显示self.b完全没问题:不是零,所有值都应该是这样。

但是,调试器还显示,与此同时,主线程正忙于取消初始化相应的 B ;它已暂停于 <... *> ,即在引用 foo 之前可以从 a 中删除。所以对我来说self.b是有道理的此时此刻将是一个不好的引用。

这似乎是一个不幸的时机——但是我怎样才能消除这种潜在的崩溃呢?我无法阻止对 bar() 的异步调用毕竟,不要发生!

最佳答案

基本上,我们在这里打破了 unowned 的先决条件:即使调试器没有显示它,Foo.b 可以 变成Foo 生命周期内的 nil。当我们声称(通过使用unowned)它不能时,编译器相信了我们,所以我们崩溃了。

似乎有两条出路。

  1. 确保 Foo.b 是最后一个对 Foo 的相应实例拥有强引用的对象。然后,这两个对象应该“一起”删除。在取消初始化 Foo.b 时(或之后),不可能调用 Foo.bar()

  2. Foo.b 设为弱引用,即将其声明为 weak var b: B?。这使得代码更加困惑,但至少可以使其安全。

关于swift - 异步函数调用与无主对象的取消初始化发生冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45283918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com