オブジェクトは、-release
または-autorelease
メッセージを送信することで解放できます。
参照カウントを使用-release
すると、すぐにデクリメントされ、割り当て解除につながる可能性があります。
デクリメントを使用-autorelease
すると、オブジェクトが作成されたスコープを超えてオブジェクトを存続させることが延期されます。たとえば、ヘルパー メソッド-createFoo
は自動解放されたオブジェクトを返す場合があります。これにより、呼び出し元は、返されたオブジェクトを、メソッドから戻ったときにすぐに割り当てを解除せずに使用でき、解放の責任者を気にする必要もありません。
ARC を使用すると、コンパイラがこれらすべての詳細を処理します。知っておく必要があるのは、 を使用すると、オブジェクトが少し長く存続する場合があるということだけautorelease
です。
この「キープ アライブ」動作は、次のようなループに影響します。
- (void)foobar
{
for (/* a long time */) {
NSMutableString *s = [NSMutableString string];
// ...
}
}
+string
メソッド onは、自動解放されたNSMutableString
オブジェクトを返します。これは、ループの繰り返しまたはメソッドの最後で自動的に割り当て解除されるわけではありません(まあ、ARC はコール スタックを調べることで巧妙な最適化を行うことができますが、これは無視します)。これは、ループ本体の内部にいる間、メモリが無限に増加することを意味します。
以下を使用した場合に注意してください。
NSMutableString *s = [[NSMutableString alloc] init];
次に、ARC はrelease
ループ本体の最後に呼び出しを挿入し、文字列はすぐに解放されます。
最初の例の無制限のメモリ増加を回避するには、明示的な自動解放プールを定義します。
- (void)foobar
{
for (/* a long time */) {
@autoreleasepool {
NSMutableString *s = [NSMutableString string];
// ...
}
}
}
これで、ループの各反復の後、自動解放プールが破棄され、プール内で自動解放されたすべてのオブジェクト (文字列を含む) がすぐに解放されます。
したがって、呼び出しているメソッドの種類と、それらが自動解放されたオブジェクトを返すかどうかによって異なります。