【问题标题】:Does ARC work with Core Graphics objects?ARC 是否适用于 Core Graphics 对象?
【发布时间】:2011-12-09 15:41:35
【问题描述】:

我最近开始了一个使用自动引用计数 (ARC) 的新项目。
当我分配了一个 CALayer 的内容时:

UIView* view = ...
UIImage* image = ...
view.layer.contents = image.CGImage

我遇到了一个错误

ARC 不允许将非 Objective-C 指针类型“CGImageRef”隐式转换为“id”

只需将 CGImageRef 转换为 id 即可隐藏错误,但我想知道 ARC 是否仍能正常工作?

【问题讨论】:

    标签: objective-c ios core-animation core-graphics automatic-ref-counting


    【解决方案1】:

    尽管史蒂夫指出了参考资料,但我相信您在上面展示的案例可能很特别。来自Transitioning to ARC Release Notes,注意“编译器处理从Cocoa方法返回的CF对象”部分:

    编译器理解返回 Core 的 Objective-C 方法 基础类型遵循历史上的 Cocoa 命名约定(参见 高级内存管理编程指南)。例如, 编译器知道,在 iOS 中,CGColor 返回的 CGColor UIColor 的方法是不拥有的。

    他们提供的代码示例:

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

    依赖于这些方法已知的 CGColors 返回(它们缺少我在上述代码中添加的 id 转换,应该很快在他们的文档中更正)。

    因为[image CGImage] 遵循命名约定,我相信CGImage 会在这里正确桥接。我认为你对 id 的演员应该是你在这里所需要的。

    【讨论】:

      【解决方案2】:

      您真的应该查看 WWDC 2011 中的 ARC 视频。它们可在开发者网站上找到并通过 iTunes 打开。特别是:

      • Session 323 – 介绍自动引用计数

      • Session 322 – Objective-C 的深度进步

      此外,ARC 参考说明:

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

      参考说明和视频都讨论了 Core Graphics(等)以及它们如何与 ARC 配合使用。

      具体来说,请查看名为“管理免费桥接”的部分

      在许多 Cocoa 应用程序中,您需要使用 Core Foundation 样式的对象,无论是来自 Core Foundation 框架本身(例如 CFArrayRef 或 CFMutableDictionaryRef) 或来自采用的框架 Core Foundation 约定,例如 Core Graphics(您可能会使用类型 像 CGColorSpaceRef 和 CGGradientRef)。

      编译器不会自动管理 Core 的生命周期 基础对象;您必须调用 CFRetain 和 CFRelease(或 对应的特定类型变体)由核心规定 基础内存管理规则(参见内存管理编程 核心基础指南)。

      如果你在 Objective-C 和 Core Foundation 风格的对象之间转换,你 需要告诉编译器对象的所有权语义 使用强制转换(在 objc/runtime.h 中定义)或核心 Foundation 风格的宏(在 NSObject.h 中定义):[...]

      Jörg Jacobsen 也对桥接选项进行了很好的总结:Managing Toll-free Bridging in an ARC’ed Environment

      __bridge_retained(注意:仅在从对象指针转换为 C 类型指针时使用):我(程序员)需要引用此对象 在 C 类型指针的黑暗世界中有一段时间是不透明的 你,弧。所以,请不要在我还在的时候释放这个对象 需要它。我(程序员)承诺自己发布它(在黑暗中 世界)当我完成它时

      __bridge_transfer(n.b.:仅在从 C 类型指针转换为对象指针时使用):我(程序员)交给你,ARC,一个 我拥有并且我不再对黑暗感兴趣的对象 对你来说是不透明的 C 类型指针的世界。每当你,ARC, 完成了那个对象,请你自己释放它,因为你知道 正确的时间,从而节省了我一些不必自己做的工作。

      __bridge:ARC,你一直在平衡你的保留和释放,因为我一直在 C 类型指针的黑暗世界中平衡我的 是…。每当我需要在黑暗世界中抓住一个物体时,我都会 自己保留它并在适当的时候释放它。我不需要任何 与你签订额外合同,ARC。

      【讨论】:

      • :) 谢谢!很高兴我能帮助你!几天前,我们迁移了一个相当大的应用程序,花了大约两天时间解决所有问题,但我对最终结果非常满意。代码少了很多,健壮了很多。 ARC很酷。这些视频对我来说是一个很棒的资源。
      【解决方案3】:

      layer.contents = (id)image.CGImage 问题的一个流行答案是layer.contents = obj_unretainedObject(image.CGImage)

      我愿意=(__bridge id)image.CGImage

      【讨论】:

      • 我建议在您的答案中添加代码格式,以提高可读性。
      猜你喜欢
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多