0

実行時に参照カウントを減らしたり削除したりするためのプログラム分析がありますか?あるいは、プログラマが手作業でカウントをインクリメントしたりデクリメントする必要がないという意味では、単に「自動」ですか?しかし、参照が作成される/消えるたびに発生します。SwiftのAutomatic Reference Countingについては何が自動ですか?

基本的に、ARCを通常の参照カウントと異なるのは何ですか?特にプログラム分析を使用している場合は、何が起こっているのかについて議論された論文がありますか?

+2

これはお使いになりましたか? https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html – Santosh

答えて

1

実行時に参照カウントを減らしたり削除したりするプログラム分析がありますか?

はありません、自動的には参照カウントを維持呼び出しを挿入するために起こってプログラム解析があります。

それとも、プログラマが手動でインクリメントし、カウントをデクリメントする必要がないという意味では、単に「自動」です...

その通り。 ARCの前に、Objective-Cプログラマはオブジェクトへの参照を維持したい場合は-retainを呼び出すように注意しなければなりませんでした。-releaseは参照で終了しました。これらのメソッドは、オブジェクトの参照カウントを増減しました。 ARCを使用すると、コンパイラはこれらの呼び出しを追加する場所を特定し、それらを挿入します(または同等のコード)。したがって、参照カウントはプログラマの観点から自動で行われます。

1

自動参照カウント(ARC)はコンパイル時に静的解析を行いますが、ではなくは実行時分析を実行します。

ARCを簡単に概念化する方法は、2パスプロセスです。最初に、あなたのコードを調べ、オブジェクト参照が導入されたり範囲外に出たりする場所にメモリ管理コード(意味的にはretainrelease pre-ARC ObjCの呼び出しに相当)を挿入します。だから、この:

func doSomething() -> Object { 
    let thing1 = Object(name: "foo") 
    var thing2 = Object(name: "bar") 
    thing2 = Object(name: "baz") 
    return thing2 
} 

...(いくつかのコンパイラ内部中間形式で)となり、このような何か:

func doSomething() -> Object { 
    let thing1 = Object(name: "foo") 
    __retain(thing1) // increment reference count so thing1 sticks around 

    var thing2 = Object(name: "bar") 
    __retain(thing2) // increment reference count so thing2 sticks around 

    let oldThing2 = thing2 // thing2 gets replaced on the next line 
    thing2 = Object(name: "baz") 
    __release(oldThing2) // get rid of the thing that got overwritten 
    __retain(thing2) // hold onto the new thing that replaced it 

    __release(thing1) // end of scope, so nothing else will use thing1 
    return __autorelease(thing2) // relinquish ownership of thing2, 
     // but only upon handing ownership over to our caller 
} 

オブジェクト参照が導入されている時間と、彼らはスコープの外に行く時間や(returnステートメントを介して)発信者に引き渡されることは、回線から回線へのプログラムセマンティクスを満たすための最低限の要件ですが、この分析レベルで停止するとメモリ管理が冗長になります。 (。thing1は、その作成後に使用されることはありませんことを例えば注意)だから、ARCが行う次のことは、より多くのこのような何か私たちの例では、擬似コード作り、冗長性を排除し、他の最適化を実行するためのフロー分析である:これは

func doSomething() -> Object { 
    _ = Object(name: "foo") // formerly thing1 
    // Object.init(name:) is called in case it has side effects, 
    // but the result is immediately discarded because it's not used 

    _ = Object(name: "bar") // formerly thing2 
    // again we call the initializer but discard the result, 
    // because the original thing2 is immediately overwritten 

    let thing2 = Object(name: "baz") 
    // no retain, because nothing happens between here and return 
    // that could affect the memory lifetime of thing2 

    return __magic_autorelease(thing2) 
    // and there's other voodoo we can do to ensure handoff to the caller 
    // without getting into retain count tracking or autorelease pools 
} 

明らかに非常に波状の概観 - ボンネットの下ではさらに多くのことが起こっているので、実際の実装はこの単純な2段階プロセスにはあまり合いませんが、概念的には非常に似ています。

これらの最初の二つは、Objective-CでARCについてです

が、ARC:いくつかのより詳細な議論については、を見てみましょうSwiftでは非常に密接に関連しているので、ARCが実際にどのように動作するかを知りたければ、そのObjC起源を見ることが最善です。

関連する問題