2012-06-19 17 views
4

我正在使用一個不基於ARC的項目的ARC兼容庫。該庫中的函數返回一個保留的UIImage *對象。有沒有辦法使用__bridge屬性讓ARC知道這個,以便它可以管理返回對象的保留計數?我想:從ARC方法中釋放一個調用無弧C函數的對象

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

但它不會讓我的UIImage *轉換爲UIImage *)。我也試過了:

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

哪個也沒有用。編譯器建議使用__bridge_retained而不是__bridge_transfer,但我相信會做與我以前相反的事情(即它會增加返回的UIImage對象上的保留計數)。

我相信正確的做法是讓C函數返回一個自動釋放對象。盡我所知,ARC假定任何返回對象的C函數都會返回一個自動釋放對象。我可以訪問這個庫的源代碼,所以我可以這樣做,但是我想知道如果我無法修改庫,是否有可以從調用方使用的解決方案。

+2

您可以禁用某些文件的ARC,而不是試圖使它們與ARC兼容。請參閱http://stackoverflow.com/questions/10184307/batch-adding-fno-objc-arc-flag-to-multiple-source-files/10184313#10184313。 –

+0

@EvanMulawski是對的。不要費心嘗試製作符合ARC標準的圖書館,根本沒有必要。 –

+0

謝謝你們兩位。我沒有試圖讓庫弧符合,它不是,我很好。我的問題是庫中有一個C函數(不是objc方法),它返回一個UIImage。我的調用模塊,符合ISO標準,調用此函數並獲取UIImage。我認爲會發生的事情是,ARC假定c函數正在返回該UIImage的自動釋放實例,所以它不會釋放它,並且UIImage會泄漏。 – neils4fun

回答

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; 
} 

在項目的目標設置,在構建階段,雙在「Compile Sources」下單擊這個.m源文件並添加非ARC標誌-fno-objc-arc(以允許您使用release方法)。

你現在有一個函數可以調用,這會減少你的UIImage的保留數,然後再一次在世界上都很好。其次,更爲戲劇性的解決方案是在圖像庫呈現的整個C接口周圍編寫自己的非ARC包裝類,以彌補那些不返回具有正確保留數的項目的方法。但是對於一次retainCount海侵來說,它似乎有很多工作要做。但是如果圖書館有它自己的弱點(例如,你正在處理一個笨拙的低級圖書館),那麼你可能會一箭雙鵰。

2

根據蘋果的Transitioning to ARC Release Notes,這裏應該使用__unsafe_unretained。

__unsafe_unretained指定不引用活動的引用,並且在沒有強引用時不設置爲nil。如果它所引用的對象被解除分配,指針就會懸空。

由於ARC和MRC(手動引用計數)具有不同的內存管理規則,因此不存在影響內存管理的關鍵字。唯一的選擇是關鍵字__unsafe_unretained,它對ARC和MRC都沒有內存管理影響。

相關問題