4

我正在使用基于 ARC 的项目中不符合 ARC 的库。该库中的函数返回一个保留UIImage *对象。有没有办法使用__bridge属性让 ARC 知道这一点,以便它可以管理返回对象的保留计数?我试过了:

UIImage *returnedImage;
returnedImage = (__bridge_transfer UIImage *)functionThatReturnsAUIImage();

但它不允许我将UIImage *a 转换为UIImage *)。我也试过:

returnedImage = (UIImage *)(__bridge_transfer void *)functionThatReturnsAUIImage();

这也没有奏效。编译器建议__bridge_retained代替__bridge_transfer,但我相信这样做会与我所追求的相反(即它会增加返回UIImage对象的保留计数)。

我相信正确的做法是让 C 函数返回一个自动释放的对象。据我所知,ARC 假定任何返回对象的 C 函数都将返回一个自动释放的对象。我可以访问这个库的源代码,所以我可以这样做,但我想知道如果我无法修改库,是否有可以从调用方使用的解决方案。

4

2 回答 2

3

bridge逻辑修饰符对您不起作用,这太糟糕了。

两种可能的方法突然出现在我面前。

首先,虽然它并不优雅,但您可以编写自己的图像发布函数,例如:

//  ImageManualMemoryManagement.h

#import <UIKit/UIKit.h>

int releaseImage(UIImage *img);

//  ImageManualMemoryManagement.m

#import "ImageManualMemoryManagement.h"

int releaseImage(UIImage *img)
{
    [img release];

    return 0;
}

在项目的目标设置中,在 Build Phases 下,双击“Compile Sources”下的这个 .m 源文件并添加非 ARC 标志-fno-objc-arc(以允许您使用该release方法)。

你现在有了一个可以调用的函数,它可以减少 UIImage 的保留计数,然后一切都好起来了。

其次,更引人注目的解决方案是围绕图像库提供的整个 C 接口编写自己的非 ARC 包装类,以纠正那些没有返回具有正确保留计数的项目的少数方法。但是对于一次retainCount 违规似乎需要做很多工作。但是,如果图书馆有它自己的弱点(例如,你正在处理一个笨拙的低级图书馆),你可能会用一块石头杀死两只鸟。

于 2012-06-23T01:57:24.193 回答
2

根据苹果的Transitioning to ARC Release Notes,这里应该使用 __unsafe_unretained。

__unsafe_unretained 指定一个不保持被引用对象活动的引用,并且在没有对该对象的强引用时不设置为 nil。如果它引用的对象被释放,则指针悬空。

因为 ARC 和 MRC(手动引用计数)的内存管理规则不同,所以没有一个对内存管理有影响的关键字起作用。唯一的选择是关键字 __unsafe_unretained,它对 ARC 和 MRC 都没有内存管理影响。

于 2012-07-20T13:27:27.873 回答