gpt4 book ai didi

ios - 手动内存管理中的弱/强 "dance"

转载 作者:可可西里 更新时间:2023-11-01 06:07:09 28 4
gpt4 key购买 nike

想象以下使用手动内存管理(也称为非 ARC)的场景:

我有一个将 block 传递给类方法的 VC。在执行 block 之前,VC 从 UINavigationController 中弹出。 __block MyVC *weakSelf = self 形式的弱引用被传递给 block ,然后 block 被转换为 MyVC *strongSelf = weakSelf(又名弱/强舞蹈)。该 block 永远不会被任何干预措施保留。

在这种情况下,我在代码中看到的是:

  1. VC的dealloc在弹出时调用。
  2. block 最终被调用。
  3. 应用程序崩溃是因为我正在访问垃圾(strongSelf 指向它)。

我的问题是:我不希望我的 VC 在该 block 最终执行之前保持事件状态,但是一旦执行该 block ,我想确认 strongSelf 是否有效。

我已经检查了这个 ( non-trivial example by Apple ),它不起作用,因为它是为 ARC 设计的。那么我怎样才能与 MMM 有相同的行为呢?理想情况下,我希望拥有 __weak 的功能:如果 retainCount 达到零,我希望它的引用指向 nil 而不是垃圾。


从 Apple 阅读这篇文章后:

In some cases you can use __unsafe_unretained if the class isn’t __weak compatible. This can, however, become impractical for nontrivial cycles because it can be hard or impossible to validate that the __unsafe_unretained pointer is still valid and still points to the same object in question.

因为我无权访问__weak 我想做的事情甚至是可能的?

最佳答案

我在 iOS 4.x 时代就与这个确切的问题作斗争。没有弱指针帮助你,这并不容易!

如果你保证 block 稍后在主线程上执行(即从 weakSelf 分配 strongSelf 的地方)那么你基本上需要一个地方来存储一个“isDead”标志,你在 VC 被释放时设置.然后在对 weakSelf/strongSelf 做任何事情之前检查这个标志。一种解决方案是:

  1. 你需要一个类,它的唯一工作就是将这个“isDead”标志存储在一个成员变量中。类似于 NSMutableBoolean 的东西。我不会写出来,它很简单,它只需要一个 BOOL 属性。
  2. 在您的 VC 的 -[NSObject init] 方法中,您创建了这个标志对象的一个​​实例,它最初应该设置为 false
  3. 然后将此对象传递给您排队等待稍后执行的任何 block ,这样它就会被 block 自动保留/释放(即不经过弱/强舞蹈)。在 block 内,在对 weakSelf 进行任何操作之前检查标志是否仍为 NO
  4. 关键当然是在VC的-[NSObject dealloc]方法里面设置flag为YES,然后释放。如果任何 block 仍在等待执行,它们本身将保留标志对象,并且当它们稍后执行时,它们将查询标志发现 VC 现在已经死了。

这听起来很麻烦(确实有点麻烦),但想法是“isDead”标志存在于 VC 的范围之外,因此与其生命周期无关。至于线程安全,只要在 VC 的 init/dealloc 方法中设置/查询标志,并且在 block 执行时(在主线程上,而不是在后台线程上),它就是线程安全的。

关于ios - 手动内存管理中的弱/强 "dance",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25666729/

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