Zaphod
Zaphod

Reputation: 7290

__unsafe_unretained and release with ARC

I must use a union containing a class pointer, but with ARC on, and as very well explained here: __unsafe_unretained NSString struct var you have to set the field __unsafe_unretained.

That means, if I understand it well, you must manage yourself its lifecycle.

For example:

typedef union FOO {
    char                                    __char;
    __unsafe_unretained NSMutableArray *    __array;
    __unsafe_unretained BarClass *          __bar;
}

If I do something like:

FOO * foo = malloc(sizeof(FOO));
foo.__bar = [[BarClass alloc] init];
... // I have fun with foo.__bar
[foo.__bar release] // this was before ARC and does not work anymore
free(foo);

How do I release foo.__bar? Because with ARC I cannot call releaseor autorelease anymore?

Upvotes: 0

Views: 551

Answers (2)

rob mayoff
rob mayoff

Reputation: 385970

The easiest way is to use a __bridge cast and CFRelease:

CFRelease((__bridge void *)foo->__bar);

Some other notes:

  1. Don't use the names __char, __array, and __bar. All identifiers that begin with two consecutive underscores are reserved by the C standard.

  2. You need to retain the object too, before the end of the statement that creates it, because at the end of that statement, ARC will release it. The easiest way to do that is by abusing CFBridgingRetain:

    foo->__bar = (__bridge id)CFBridgingRetain([[NSObject alloc] init]);
    
  3. You might be better off just turning FOO into an Objective-C class so that it can hold strong references.

Upvotes: 2

Daij-Djan
Daij-Djan

Reputation: 50129

I would hold an additional strong pointer to it, then you dont have to worry at all about releasing it.

BarClass *myStrongBar = [[BarClass alloc] init];

FOO * foo = malloc(sizeof(FOO));
foo.__bar = myStrongBar;
... // I have fun with foo.__bar
free(foo);

Upvotes: -1

Related Questions