使用ARC在void*指针中分配Objective-C对象

Dmi*_*try 9 objective-c automatic-ref-counting

我需要在void*指针的C结构中保留Objective C对象.此结构在外部库中定义,我无法更改定义.

让我们说它被定义为:

struct c_context {
  void* user_data;
};
Run Code Online (Sandbox Code Playgroud)

而我在代码中需要做的是:

struct c_context *context;
...
context->user_data = [[MYObjCClass alloc] init];
Run Code Online (Sandbox Code Playgroud)

但是,我需要确保MYObjCClass保留该对象.

所以我的问题是:

  1. 如何转换(或桥接)它来void*告诉编译器保留obj-c对象?
  2. 以后在需要清理数据时如何释放对象?

Rob*_*ier 12

您不能使用ARC来管理结构中的对象.您负责手动跟踪其内存管理.不鼓励您以这种方式存储对象.

如果必须以这种方式跟踪内存,则必须告诉ARC,当您将对象放入结构时,您将对该对象负责:

context->user_data = CFBridgingRetain([[MYObjCClass alloc] init]);
Run Code Online (Sandbox Code Playgroud)

这告诉ARC它不再负责返回的对象init,并添加一个手册,retain以便context->user_data现在是所有者.

完成对象后,可以将其传回ARC,也可以将其释放.要将其转回ARC:

MYObjCClass *something = CFBridgingRelease(context->user_data);
context->user_data = NULL;
Run Code Online (Sandbox Code Playgroud)

这告诉ARC它负责对象并删除你的保留.您应该使指针为NULL,因为context->user_data不再拥有此对象,并且该对象可能随时消失.

你也可以直接发布它:

CFRelease(context->user_data);
context->user_data = NULL;
Run Code Online (Sandbox Code Playgroud)

同样,这是最后的手段.通常,您不应将ObjC对象存储在结构中,因为ARC无法管理它们.

作为旁注,虽然我一般不推荐使用ObjC++,但可以使用带有析构函数的C++结构来自动执行此操作.在某些情况下,这可能比C中的手动内存管理更可取.