5

特に、この種のコードは常に意図したとおりに機能しますか (MyResourceGuard は、init メソッドで排他的リソースをロックし、dealloc メソッドでロックを解放するオブジェクトです)。

NSLog(@"About to capture some exclusive resource.");
{
  MyResourceGuard* guard = [MyResourceGuard new];
  // Do something with the exclusive resource here.
}
// guard is out of scope, therefore its dealloc should have
// been called right away and the resource should already
// be free again at this point.

Java ガベージ コレクションなどとは対照的に、ARC は参照カウントがゼロになるとすぐにオブジェクトを破棄することを本やブログで読んだことがありますが (それ自体が都合のよいときではありません)、公式の記事ではこれを読んだことがありません。 Apple によるドキュメント。それが本当なら、なぜ ARC で導入された新しい @autoreleasepool キーワードが必要になるのでしょうか?

デバッグから、try- catch -block で例外が発生した場合を除いて、オブジェクトがすぐに解放されるのを常に見てきました C奇妙なこと?)。

4

2 に答える 2

5

いいえ。例が示すように、ObjC オブジェクトの決定論的スコープ ベースの破壊はありません。

たとえば、次のプログラムではデッドロックが発生する可能性があります。

{ MyResourceGuard* guard = [MyResourceGuard new]; }
{ MyResourceGuard* guard = [MyResourceGuard new]; }

この機能が必要な場合にできる最善の方法は、C++ 型 ( SBRM、RAII ) を使用することです。Objective-C++ でも利用できます (ただし、objc オブジェクトには適用できません)。

それは近づいていますが、呼び出されるために参照カウントがゼロになるまで待つ必要がある-deallocため、保証がオフになっています (通常は != always )。この問題は、実際には、依存したり使用したりしない理由-retainCount(利用可能な場合) と非常によく似ています。例: 自動解放プール、例外、ランタイムまたは ARC 生成コードの変更、コンパイラの最適化、異なるコード生成フラグを持つ実装の使用により、objc オブジェクトの寿命が範囲を超えて延長される可能性があります。

アップデート

詳細、保証 (および保証の欠如) を含む、clang のサイトにある ARCのページ全体は、このテーマについてよく読んでいますが、特に:

6.1. 正確なライフタイム セマンティクス

一般に、ARC は、__strong オブジェクトに保持されている保持可能なオブジェクト ポインターが、そのオブジェクトの正式な有効期間全体にわたって保持されるという不変条件を維持します。この不変条件に従うオブジェクトには、正確な有効期間のセマンティクスがあります。

デフォルトでは、自動保存期間のローカル変数には正確な有効期間セマンティクスがありません。このようなオブジェクトは、保持可能なオブジェクト ポインター型の値を保持する単純な強参照であり、これらの値はローカル制御下の値の最適化の対象となります。

理論的根拠: これらの正確な有効期間のセマンティクスを厳密に適用することは禁止されています。理論的にはオブジェクトの寿命を縮める可能性のある多くの有用な最適化は不可能になります。本質的に、それはあまりにも多くを約束します。

保持可能なオブジェクト所有者タイプと自動保存期間のローカル変数は、objc_precise_lifetime 属性で注釈を付けて、正確な有効期間セマンティクスを持つオブジェクトと見なす必要があることを示すことができます。

理論的根拠: それでも、オブジェクトが使用されていないように見える場合でも、オブジェクトを正確な時間に強制的に解放できると便利な場合があります。これはあまり一般的ではないため、これらのセマンティクスを明示的に要求することの構文上の重みが負担になることはなく、コードがより明確になる可能性さえあります。

属性を使用したとしても、オブジェクトの有効期間ではなく、その強力なローカル変数objc_precise_lifetimeの参照カウント操作に適用されます。

于 2012-11-16T13:28:08.997 に答える
0

この種のコードは常に機能します。(または、少なくとも ARC が現在のように機能している限り) ARC でのオブジェクトのライフサイクルの小さな例:

{
    NSString *a = [[NSString alloc] init]; //object allocation
    a = nil; // object is deallocated as it was created in this scope

    NSString *b = [NSString string]; //method call which returns an object (always autoreleased)
    b = nil; // object is not deallocated as it was not created in this scope and is therefore autorelased
}
于 2012-11-16T13:27:39.187 に答える