Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retaining ARC objects in c++ classes

I have some code that must remain as c++, but I need to store objective-c objects in these c++ classes. The objects will not be referenced anywhere else while they are stored here, so I can't have them deleted out from under me. Before ARC, I just retained them before putting them into the c++ class, and autoreleased them when they were removed. Everything worked fines.

But with ARC, I'm not sure what to do. Is making the c++ variables __unsafe_unretained enough? Doesn't seem like it is because once the obj-c code isn't using that objects anymore it will be deleted, or am I not understanding what __unsafe_unretained does. Can I call CFRetain() and CFAutorelase() under ARC?

What is the right way to deal with this under ARC? What does NSArray do down deep to keep the objects it is storing?

like image 852
Roger Gilbrat Avatar asked Dec 20 '11 00:12

Roger Gilbrat


2 Answers

You can call CFRetain and CFRelease under ARC. You are responsible for balancing each CFRetain with a CFRelease, because ARC does not pay any attention to these functions.

There is no CFAutorelease function. You could perform an autorelease using objc_msgSend(myObject, sel_registerName("autorelease")). The hoops you are jumping through here should be a red flag that you're doing something that's probably wrong.

Generally it's better under ARC to find a way not to store object references in otherwise-untyped blobs of memory. Note that member variables of C++ objects can be qualified __strong or __weak if you compile them as Objective-C++.

UPDATE

The public SDKs of Mac OS X 10.9 and iOS 7.0 include a CFAutorelease function, which you can use even under ARC.

like image 192
rob mayoff Avatar answered Sep 23 '22 08:09

rob mayoff


I had some success using bridge casting when converting some old code to Xcode 4.3. It wouldn't let me bridge directly but I was able to bridge via a void *. I only did this to get some old code working so I can't guarantee it works perfectly.

struct {
  __unsafe_unretained UIView *view;
} blah;
...
blah = malloc(sizeof(blah));
...
// Cast the pointer with +1 to retain count
blah->view = (__bridge UIView *) (__bridge_retained void *) myView;
...
// blah->view can be used as normal
...
// Transfer ownership back to ARC for releasing
myView = (__bridge_transfer UIView *)(__bridge void *)blah->view;
like image 41
bw1024 Avatar answered Sep 23 '22 08:09

bw1024