Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning Objective-C object in a void* pointer with ARC

I need to keep an Objective C object in a C struct in void* pointer. This struct is defined in external library and I can not change the definition.

Let's say it is defined as:

struct c_context {
  void* user_data;
};

and what I need to do in my code is this:

struct c_context *context;
...
context->user_data = [[MYObjCClass alloc] init];

However, I need to make sure that the MYObjCClass object will be retained.

So my question is:

  1. How to cast (or bridge) it to void* telling the compiler to retain the obj-c object?
  2. How to release the object later when I need to clean up the data?
like image 215
Dmitry Avatar asked Aug 14 '13 14:08

Dmitry


1 Answers

You cannot use ARC to manage an object in a struct. You are responsible for tracking its memory management manually. You are discouraged from storing objects this way.

If you must track memory this way, you must tell ARC that you are taking responsibility for the object when you put it into the struct:

context->user_data = CFBridgingRetain([[MYObjCClass alloc] init]);

This tells ARC that it is no longer responsible for the object returned by init, and adds a manual retain so that context->user_data is now the owner.

When you are done with the object, you can either transfer it back to ARC, or you can release it. To transfer it back to ARC:

MYObjCClass *something = CFBridgingRelease(context->user_data);
context->user_data = NULL;

This tells ARC it is responsible for the object and removes your retain. You should NULL the pointer because context->user_data no longer owns this object and the object may disappear at any time.

You can also directly release it:

CFRelease(context->user_data);
context->user_data = NULL;

Again, this is a last-resort technique. In general you should not store ObjC objects in structs since ARC cannot manage them.

As a side note, while I do not generally recommend ObjC++, it is possible to use a C++ struct with a destructor to automate this. In some cases, this may be preferable to manually memory management in C.

like image 153
Rob Napier Avatar answered Nov 09 '22 05:11

Rob Napier