gpt4 book ai didi

objective-c - 当没有其他引用保留对象时,如何安全地将 id 对象存储在 ARC 下的 C++ void* 成员中?

转载 作者:太空狗 更新时间:2023-10-30 03:17:45 27 4
gpt4 key购买 nike

我正在使用 Box2D (C++),我创建了一个 Objective-C 对象并将其分配给 Box2D 主体的 userData 属性,该属性的类型为 void* .

现在在某些情况下,void* userData 可能是对该 ObjC 对象的唯一事件引用。因此,因为我在作业中使用了 (__bridge void*),所以 ARC 放手了。这是我需要解决的问题。

我一直在思考防止这种情况发生的选项?我读了Clang's ARC documentation ,特别是关于桥梁类型转换的部分(以及关于 SO 的问答)以及对他们认为“不正确”的各种桥梁类型转换结构的点头。

不过,我的第一个想法是在对 userData 的初始赋值中使用 (__bridge_retained void*)。但这让我想知道如何平衡保留?我显然不能向对象发送释放。

那么我是否必须 CFRelease() 对象?还是需要 CFBridgingRelease()?或者两者在这里都是非法的?

(__bridge_transfer void*)userData 转换为临时 id 类型是否足够,也许之后将 userData 设置为 NULL?这是个好主意吗?

我知道替代方案是为 userData 对象保留一个单独的 NSArray/NSDictionary 并使它们与Box2D 主体,与 Box2D 主体同步添加和删除它们。

但这感觉有点矫枉过正,因为在这里我知道我在做什么,我知道只要 Box2D 主体处于事件状态,我就需要 +1 对象,并且 -1 移除 Box2D 主体时的对象。另外我知道只有两种方法可以添加和删除 Box2D 主体,并且在我的框架中甚至不可能直接访问 userData 因为所有 Box2D 对象都隐藏在 Objective-C 接口(interface)之后/ wrapper 。

暂且把可能的“病态”放在一边,在这种情况下你建议我应该怎么做?

最佳答案

__bridge_retained 表示“通过保留此 ARC 对象将其发送到无 ARC 区域”。当您需要创建一个“未跟踪的”void * 时调用它。因此,在您的情况下,userData = (__bridge_retained void *)obj

__bridge_transfer 意思是“通过释放它把这个对象从无 ARC 区域拉回来”。当您想要有效地使 void * 无效时,您可以调用它。所以,obj = (__bridge_transfer id)userData。在此之后,userData 指针不能安全使用;相反,您只使用 obj。当 obj 超出范围时,ARC 将最后一次释放它。这可能需要专门为此目的创建一个临时 id

因此,在您的情况下,当您将对象发送到 Box2D 中时,您确实希望使用 __bridge_retained,而当您想让 无效时使用 __bridge_transfer用户数据。如果您需要访问作为 Objective-C 对象的 userData 但又不使指针无效,请使用普通的 __bridge

关于objective-c - 当没有其他引用保留对象时,如何安全地将 id 对象存储在 ARC 下的 C++ void* 成员中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14782395/

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