As we know it is very easy to make conversion between toll-free bridged types and objective-c types such as CFArrayRef and NSArray. Yesterday, I found a piece of code that convert CGImageRef (which is not a tool-free bridged type) to id as below:
CALayer *imgLayer = [CALayer layer];
imgLayer.contents = (id)aImage.CGImage;
However, it works fine. But I don’t understand it, because CGImageRef is not belong to toll-free bridged types according to apple’s document. Look at the second line code, imgLayer should retain the value assigned to the property contents. Because CGImageRef is converted to id so I think in the property contents’ setter method it will send a retain message to that object like this [xxx retain]. But aImage.CGImage is not an object so I don’t think this retain message will perform correctly (however it will). So my question is what is the actual action behind this conversion?
These methods are an exception to the rule that Apple added for convenience. Since the compiler knows about Objective-C naming conventions and the implied memory management, Core Foundation objects returned by objective-C functions will be automatically converted and handled correctly.
See the section The Compiler Handles CF Objects Returned From Cocoa Methods in this document
Toll-free bridging is a bit of an outdated term. It referred to the seamless casting between Core Foundation C objects and Objective-C objects. However, with ARC the transition is no longer as seamless since the compiler needs hints about what to do with the corresponding objects after bridging them. In this case, though, it gets its hints from the naming conventions of the method.
Furthermore, all Core Foundation objects can essentially be cast to Objective-C objects. If there is no corresponding type then they will simply become a special catch-all class (
NSCFType) that was designed for this purpose.