使用ARC返回一个已经自动释放的CFTypeRef对象

9
我是一名新手,对于LLVM和Objective-C中的自动引用计数(ARC)还不熟悉,并且关于从我的Objective-C函数返回CGImageRefs有一个问题。在手动引用计数的时代,我们可以将CGImageRef简单地转换为id,将其autorelease,然后返回原始的CGImageRef。但是在ARC中,虽然我们知道可以直接让ARC系统对可保留对象进行autorelease并返回,但我没有找到对CFTypeRefs实现这种方式的方法。
这是我在禁用ARC时所能做的:
- (CGImageRef)image {
    CGImageRef myImage;
    id myImageID = (id)myImage;
    [myImageID autorelease];
    return myImage;
}

所以,我想创建一种方法,使用ARC返回一个不由调用者拥有的CGImageRef。如果有更好的方法来完成同样的事情,我非常乐意听取建议。我知道UIImage使用CGImage属性做了类似的事情。
编辑:虽然为特定文件禁用ARC是实现此目的的有效方法,但我更喜欢在整个代码中使用纯ARC。这在与他人分享特定文件的特定代码时非常方便,因为他们不需要更改任何给定文件的构建设置。为了利用ARC系统自动释放CFTypeRef,可以执行以下操作:
__attribute__((ns_returns_autoreleased))
id CGImageReturnAutoreleased (CGImageRef original) {
    // CGImageRetain(original);
    return (__bridge id)original;
}

然后只需执行 return (__bridge CGImageRef)CGImageReturnAutoreleased(myImage) 来返回一个自动释放的图像。


我曾经遇到过非常类似的问题,但是当我实现了那个函数并像你一样尝试使用它时,Xcode的分析器指出它会泄漏内存。所以,我将我的方法名更改为以new开头(- (CFTypeRef)newCFTypeObject),这样它就符合命名规范来返回一个已保留的对象。难道没有什么简单的方法可以返回一个自动释放的CFType吗?(不需要任何帮助函数或外部文件) - Sorig
我使用了您的代码,但是它也有泄漏问题。 - user501836
我建议不要懒惰,只需在正确的位置插入适当的CFRelease。这样可以节省打字时间,并使您的代码对他人易读。如果您可以从NS类型开始使用toll free bridging而无需更改所有权,则没问题。否则,您会污染代码。 - uchuugaka
2个回答

3

更新

从OS X 10.9和iOS 7.0开始,公共SDK包括一个CFAutorelease函数。

原文

您可以创建如下的实用函数:

void cfAutorelease(CFTypeRef *ref) {
    [[(id)ref retain] autorelease];
}

将其放入一个禁用ARC编译的文件中。您需要传递编译器标志-fno-objc-arc以禁用该文件的ARC。在Xcode 4中,选择您的项目,然后选择Build Phases选项卡。打开Compile Sources部分。双击包含实用函数的文件,并将-fno-objc-arc放入弹出框中。


你并没有真正使用ARC - 你是在没有使用它的情况下进行操作。如果有更简单的方法就好了。 - Sorig
呃,那是一个相当的黑科技。它可以工作,但我不建议这样做。如果你真的需要它自动释放,请使用__attribute__((ns_returns_autoreleased))。 - steipete

-1
如果您正在使用ARC,则不用担心autoreleasing对象。
UIImage *image;
image.CGImage

始终返回autorelease对象本身。


它可以使用__bridge进行无工具桥接。 - Nagaraj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接