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です。

考えられる 2 つのアプローチが思い浮かびます。

まず、エレガントではありませんが、独自のイメージ リリース関数を記述できます。次に例を示します。

//  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 違反を 1 回行うだけでも、かなりの労力がかかるようです。しかし、ライブラリに独自の弱点がある場合 (たとえば、扱いにくい低レベルのライブラリを扱っている場合)、一石二鳥かもしれません。

于 2012-06-23T01:57:24.193 に答える
2

Apple のTransitioning to ARC Release Notesによると、ここでは __unsafe_unretained を使用する必要があります。

__unsafe_unretained は、参照先のオブジェクトを存続させず、オブジェクトへの強い参照がない場合に nil に設定されない参照を指定します。参照するオブジェクトの割り当てが解除された場合、ポインターはぶら下がったままになります。

ARC と MRC (手動参照カウント) ではメモリ管理規則が異なるため、メモリ管理に影響を与えるキーワードは機能しません。唯一の選択肢は、ARC と MRC の両方にメモリ管理の影響を与えないキーワード __unsafe_unretained です。

于 2012-07-20T13:27:27.873 に答える