Does ARC work with Core Graphics objects?

吃可爱长大的小学妹 提交于 2019-11-26 22:09:24
Steve

You should really check out the ARC videos from WWDC 2011. They are available on the developer site and open through iTunes. Especially:

• Session 323 – Introducing Automatic Reference Counting

• Session 322 – Objective-C Advancements in Depth

Also, the ARC reference notes:

https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

Both the reference notes and the videos discuss Core Graphics (et al) and how they work with ARC.

Specifically, look at the section called "Managing Toll-Free Bridging"

In many Cocoa applications, you need to use Core Foundation-style objects, whether from the Core Foundation framework itself (such as CFArrayRef or CFMutableDictionaryRef) or from frameworks that adopt Core Foundation conventions such as Core Graphics (you might use types like CGColorSpaceRef and CGGradientRef).

The compiler does not automatically manage the lifetimes of Core Foundation objects; you must call CFRetain and CFRelease (or the corresponding type-specific variants) as dictated by the Core Foundation memory management rules (see Memory Management Programming Guide for Core Foundation).

If you cast between Objective-C and Core Foundation-style objects, you need to tell the compiler about the ownership semantics of the object using either a cast (defined in objc/runtime.h) or a Core Foundation-style macro (defined in NSObject.h): [...]

Jörg Jacobsen has a good summary overview of the bridging options as well: Managing Toll-free Bridging in an ARC’ed Environment.

__bridge_retained (n.b.: only use it when casting from object pointer to C type pointer): I (the programmer) need to reference this object for some time in the dark world of C type pointers which is opaque to you, ARC. So please, please do not release this object while I still need it. I (the programmer) promise to release it myself (in the dark world) when I’m done with it

__bridge_transfer (n.b.: only use it when casting from C type pointer to object pointer): I (the programmer) hand over to you, ARC, an object that I own and that I am no longer interested in in the dark world of C type pointers that is opaque to you. Whenever you, ARC, are done with that object please release it yourself, because you know the right time and thus save me some work not having to do it myself.

__bridge: ARC, you keep balancing out your retains and releases as I keep balancing out mine in the dark world of C type pointers which is…. Whenever I need to hold on to an object in the dark world I will retain it myself and release it when appropriate. I don’t need any extra contract with you, ARC.

Brad Larson

Despite the references pointed out by Steve, I believe the case you show above might be special. From the Transitioning to ARC Release Notes, pay attention to the section "The Compiler Handles CF Objects Returned From Cocoa Methods":

The compiler understands Objective-C methods that return Core Foundation types follow the historical Cocoa naming conventions (see Advanced Memory Management Programming Guide). For example, the compiler knows that, in iOS, the CGColor returned by the CGColor method of UIColor is not owned.

The code example they provide:

gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
                                                 (id)[[UIColor lightGrayColor] CGColor], nil];

relies on the known return of CGColors from these methods (they are missing the cast to id that I've added in the above code, which should be corrected in their documentation soon).

Because [image CGImage] follows the naming conventions, I believe the CGImage will be bridged properly here. I think that your cast to id should be all that you need here.

debleek63

One popular answer to layer.contents = (id)image.CGImage question is layer.contents = obj_unretainedObject(image.CGImage).

I do =(__bridge id)image.CGImage.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!