3

I'm writing a game using the Chipmunk physics engine, and I'd like to store a pointer to an Objective-C object in every body's userData field. I know I need to use a bridging cast to cast between id and void *, but I'm not sure the way I'm doing it is safe:

// When body is created
cpBody *body = cpBodyNew(...);
UserData *userData = [[UserData alloc] init];
cpBodySetUserData(body, CFBridgingRetain(body));

...

// When body is destroyed
UserData *userData = cpBodyGetUserData(body);
CFBridgingRelease(userData);
cpBodyFree(body);

This code seems to work, but I've also read that you're only supposed to use CFBridging*() on objects that can be toll-free bridged to Core Foundation types. Since UserData is derived from NSObject, and NSObject isn't on the list of toll-free bridged types, I seem to be breaking that rule.

Is my code okay because I eventually call CFBridgingRelease and don't try to pass the object to any other Core Foundation functions, or is there another way I should be going about transferring Objective-C objects in and out of C?

godel9
  • 7,179
  • 1
  • 30
  • 51
  • Perhaps you could also use bridge casts. To set: (__bridge void *) myData, to get: (__bridge id) myData() – Jasper Blues Nov 02 '13 at 03:22
  • 2
    @JasperBlues, that works if the `UserData` object is guaranteed to survive at least as long as any of these `void*` references. It doesn't extend the lifetime to make it so, though, whereas the `CFBridgingRetain()` does. – Ken Thomases Nov 02 '13 at 03:44
  • @KenThomases - Ah! Ok, understood. Thanks for the tute. – Jasper Blues Nov 02 '13 at 03:50

1 Answers1

5

It's safe. NSObject is toll-free bridged to a generic CFTypeRef. Also, I'm assuming you aren't calling any other Core Foundation functions on the void*, so it hardly matters.

Ken Thomases
  • 83,395
  • 7
  • 101
  • 140
  • Thanks for the quick reply! It's okay even though `NSObject` isn't on the [list of toll-free bridged types](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html)? I updated my question to clarify the concern. – godel9 Nov 02 '13 at 02:57
  • 3
    Here's a statement from a Cocoa framework engineer: http://www.cocoabuilder.com/archive/cocoa/95007-toll-free-bridging-of-nsobject.html#95680 – Ken Thomases Nov 02 '13 at 03:42
  • Perfect! I appreciate the help. – godel9 Nov 02 '13 at 05:35
  • @godel9: With "Jump to definition" in Xcode you can also see that CFBridgingRetain/CFBridgingRelease are just inline function wrappers for __bridge_retained/__bridge_transfer. – Martin R Nov 02 '13 at 10:13