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

Lea*_*s2D 15 casting objective-c void-pointers automatic-ref-counting

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

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

我一直在思考防止这种情况发生的选择吗?我阅读了Clang的ARC文档,特别是关于桥梁铸造的部分(以及关于SO的Q&A)以及对他们认为"形成不良"的各种桥梁铸造结构的点头.

不过,我的第一个想法是(__bridge_retained void*)在初始分配给userData时使用.但这让我想知道如何平衡保留?我显然无法向对象发送释放.

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

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

我所知道的替代办法是保留独立NSArray/ NSDictionaryuserData对象,让他们在与Box2D的身体的寿命同步,添加和同步与他们的Box2D的身体移除它们.

但这感觉就像矫枉过正,因为在这里我知道我在做什么,我知道+1只要Box2D主体处于活动状态-1就需要对象,并且当Box2D主体被移除时我需要对象.另外我知道只有两种方法可以添加和删除Box2D主体,并且userData在我的框架中甚至无法直接访问,因为所有Box2D对象都隐藏在Objective-C接口/包装器后面.

暂时搁置"不良形式",你会建议我在这种情况下做什么?

nne*_*neo 25

__bridge_retained表示"通过保留它将此ARC对象发送到无ARC的土地".当你需要创建一个"未跟踪"时,你可以调用它void *.所以,在你的情况下,userData = (__bridge_retained void *)obj.

__bridge_transfer意思是"通过释放它将该物体从无ARC土地拉回来".当你想要有效地使其无效时,你可以调用它void *.所以,obj = (__bridge_transfer id)userData.在此之后,userData指针不安全使用; 相反,你只能使用obj.如果obj超出范围,ARC将发布它的最后一次.这可能需要id仅为此目的创建一个临时的.

因此,在您的情况下,您确实希望在__bridge_retained将对象发送到Box2D __bridge_transfer时使用,并在您想要使其无效时使用userData.如果您需要访问userData作为Objective-C对象但不使指针无效,请使用plain __bridge.