gpt4 book ai didi

ios - 如何防止在 GCD 中释放对象?

转载 作者:行者123 更新时间:2023-11-28 14:34:05 26 4
gpt4 key购买 nike

这个函数应该重新安排工作项的执行:

class MyClass {

var id: String?
var workItem: DispatchWorkItem?
var isDoing = false

func myFunction() {

guard let id = self.id else { return }

isDoing = true
NotificationCenter.default.post(name: MyNotification, object: nil, userInfo: ["id": id])
workItem?.cancel()

workItem = DispatchWorkItem {
self.isDoing = false
NotificationCenter.default.post(name: MyNotification, object: nil, userInfo: ["id": id])
}

if let workItem = workItem {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(10), execute: workItem)
}
}
}

它在开发中运行良好,但设计似乎很可疑,所以我问了一些基本问题:

  1. 如果在队列尝试执行 workItem 之前调用 workItem?.cancel()workItem 是否可以为 nil?<
  2. 在执行 workItem 时,workItem 中的 id 是否可以为 nil,或者它是否由作用域 let id = self.编号?
  3. workItem 中的 isDoing 是否已经在执行 workItem 时被释放,如果 MyClass 对象已被释放?换句话说,当 MyClass 对象被释放时,调度的 workItem 会发生什么?

最佳答案

  1. 不太清楚你的意思。您不会在任何地方取消 workItem

  2. 不,它不能是 nil,因为您正在使用局部变量 - self.id 的副本。通过使用 guard,您可以确保局部变量 id 不为 nil,并且闭包保持对捕获值的强引用(默认情况下),因此它不会被释放。

  3. isDoingMyClass 的实例变量,因此在释放 MyClass 实例之前不能释放它。问题是,在您的情况下 MyClass 无法被释放,因为您正在查看一个强引用循环。默认情况下,闭包保持对捕获值的强引用,并且您正在捕获 self。由于 self 保持对 workItem 的强引用,这反过来又保持对捕获 self 的闭包的强引用,因此引用周期。

通常,当捕获 self 时,您使用捕获列表来处理对 self 的弱引用,并检查它是否尚未被释放

workItem = DispatchWorkItem { [weak self] in
guard let strongSelf = self else { return }
// do stuff with strongSelf
}

关于ios - 如何防止在 GCD 中释放对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51023959/

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