0

If I have the following code:

// objective C++ code .mm
id<MTLTexture> texture = ...;
void* ptr = (void*)CFBridgingRetain(texture);
share_ptr_with_native_code(ptr);
[texture do_stuff]; // is this valid?

// native code .cpp
void share_ptr_with_native(void* ptr)
{
  ptr->do_stuff();
  CFBridgingRelease(ptr);
}

Will texture be valid and retained by ARC again after the call to share_ptr_with_native()?

Mrb83
  • 85
  • 5
  • This should work fine. That having been said, if you're writing this sort of code, you really should be running this through the static analyzer. The `share_ptr_with_native` is releasing something it doesn't own, violating [basic memory management rule](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH) #4. The static analyzer (which you definitely have to check out if you're doing this sort of stuff) could potentially get confused without a `CF_RELEASES_ARGUMENT` decoration. – Rob Mar 02 '18 at 05:44

2 Answers2

2

Other than various errors in your code snippet, yes, the line in question is valid. ARC continues to maintain its own strong reference to object while it's still in use in the top code, in addition to the one that you become responsible for. CFBridgingRetain() has a +1 effect on the retain count of the object, hence "retain" in its name.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • Even though the code is only meant to be hypothetical to illustrate the question, I edited it to be more correct. The only invalid thing now should be the ptr->do_stuff() line, which just abstractly represents C++ work on the Objective C object. I didn't realise CFBridgingRetain worked by just incrementing the reference count of the ARC object. The language of the docs made me think that ARC was handing over the object to native code and forgetting about it, which is obviously not the case. Anyway, thanks for clarifying. – Mrb83 Mar 02 '18 at 05:37
  • And obviously the [texture do_stuff] call is hypothetical as well. – Mrb83 Mar 02 '18 at 05:45
2

Even everything said is right, it would be nicer if you change your

CFBridgingRelease(ptr);

to

CFRelease(ptr) .

__bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you. You are responsible for calling CFRelease or a related function to relinquish ownership of the object.

Taken from https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html.

Maik
  • 85
  • 8