2

編集:以下に定義されている問題は、実際にこのコードで発生しました:

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        XYZPerson *myPerson = [XYZPerson person];
        myPerson = nil;
        NSLog(@"The end.");
    }
}

メソッド 'person' はファクトリ メソッドです。


次のコードがあります。

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        XYZPerson *myPerson = [[XYZPerson alloc] init];
        myPerson = nil;
        NSLog(@"The end.");
    }
}

XYZPerson は dealloc メソッドをオーバーライドして、NSLog で何かを出力します。上記のコードは次のような出力を期待しています。

Dealloc!
The end.

しかし、それは私が期待したとおりではありません:

The end.
Dealloc!

私は何か間違ったことをしていますか、それとも ARC の概念を誤解していますか?

4

2 に答える 2

4

ARC は、オブジェクトがコンパイル時に自動的に参照カウントされることを保証します。さらに進んで、コードがアルゴリズム的に完全に首尾一貫している必要があります (たとえば、キャスト間で変換しようとしたときにエラーとして現れvoid*ますid。ARC では、そのようなキャスト全体でメモリ管理ポリシーを修飾する必要があります)。

ARC はガベージ コレクターではありません。スキャンもスレッド化もストップ・ザ・ワールド動作もありません。これは、自動サイクル検出などを犠牲にして、より予測可能な動作を意味します。

ARC はオブジェクトの寿命が自動的に管理されることを保証しますが、ARC は「オブジェクトが少なくともコードで使用されているよりも長く、おそらくそれよりも長く存続する」ことを保証しません。

実際、コードの最適化レベルと、呼び出したファクトリ メソッドが ARC と manual-retain-release [MRR] ソース ファイルでコンパイルされているかどうかの両方に応じて、寿命が変わることがあります。また、寿命は、コンパイラやランタイムのリリースによって変わる可能性があります。

autoreleaseたとえば、ファクトリ メソッドを呼び出す ARC コードは、全体を短絡することがあります。

恐ろしく聞こえますが、それはアルゴリズムの一貫性要件によるものではありません。(単純な古い MRR の場合のように) あいまいな動作があってはならないため、リリースによって寿命が変わる可能性があっても、コードに影響を与えることはありません。

もちろん、これはメソッド間に順序の依存関係があってはならないdeallocことを意味します。MRR の下でメソッド間に順序の依存関係を持つことdeallocは常に厄介なことであったため、これは面倒な要件ではありません。

于 2013-02-03T21:27:07.413 に答える