ARC の下で、次のような構造体を宣言できるとします。
typedef struct {
__strong NSObject *someObject;
int someInteger;
} MyStruct;
次に、次のようなコードを記述できます。
MyStruct *thing = malloc(sizeof(MyStruct));
問題:malloc
返されるメモリをゼロで埋めません。ランダムthing->someObject
な値も同様です - 必ずしも NULL ではありません。次に、次のように値を割り当てます。
thing->someObject = [[NSObject alloc] init];
内部では、ARC はそれを次のようなコードに変換します。
NSObject *temporary = [[NSObject alloc] init];
[thing->someObject release];
thing->someObject = temporary;
ここでの問題は、プログラムがrelease
ランダムな値を送信したことです! この時点でアプリがクラッシュする可能性があります。
これを防ぐために、ARC は への呼び出しを認識し、NULL へmalloc
の設定を処理する必要があると言うかもしれません。someObject
問題はmalloc
、次のように他の関数にラップされる可能性があることです。
void *myAllocate(size_t size) {
void *p = malloc(size);
if (!p) {
// malloc failed. Try to free up some memory.
clearCaches();
p = malloc(size);
}
return p;
}
OK、今度は ARC も関数について知る必要がありますmyAllocate
...そしてそれは、バイナリとして取得した静的ライブラリ内にある可能性があります。
アプリには、毎回使用せずに古い割り当てをリサイクルする独自のメモリ アロケータがある場合もありfree
ますmalloc
。そのため、メモリを返す前にメモリをゼロで埋めるように変更malloc
しても機能しません。ARC は、プログラム内のすべてのカスタム アロケーターを認識している必要があります。
これを確実に機能させることは非常に困難です。代わりに、ARCの作成者はあきらめて、「忘れてください。__strong
および参照を構造体に入れることはできません__weak
。」</p>
__unsafe_unretained
そのため、ARC に「これが参照するオブジェクトの所有権を管理しようとしないでください」と指示
した場合にのみ、オブジェクト ポインターを構造体に配置できます。</p>
__unsafe_unretained
おそらくCFRetain
andを使用して、オブジェクト参照を含む構造体を使用して、CFRelease
それらを手動で保持および解放することができます。次に、そのような構造体の配列を作成できます。これはエラーが発生しやすいため、プロファイラーがパフォーマンスにとって重要であると判断した場合にのみ実行してください。
代わりに、構造体の代わりに新しい Objective-C クラスを作成するだけです。@property
構造体に入れるフィールドごとにクラスを指定します。を使用しNSMutableArray
て、この新しいクラスのインスタンスの配列を管理します。