2016-08-25 7 views
1

私はARCのチュートリアルをたどり、このコードを提供しました。ARCとその仕組み

次のViewControllerクラス、その下にVehicleクラスがあります。

私が得たことは、ARCが本質的にインスタンス化されたクラスを追跡し、そのためのメモリを割り当てることでした。インスタンスの「強い」参照が作成されると、円弧はインスタンスへの参照数を増やします。それらのすべてがnilに設定されると、ARCはそのインスタンスをメモリーから割り振り解除します。インストラクターはまた、すべての参照が使用されていないときには、メモリから割り当てを解除します。私は彼らが "使用されていない"部分をよく理解していなかったので、コードなしの別のView Controllerを表示するボタンを追加することにしました。次のビューコントローラに移動すると、ビューコントローラ1の参照としてdeinitが呼び出され、現在は使用されていないためメモリから割り当てが解除されると考えました。これは事実ではなく、裁判官は呼ばれなかった。したがって、私はあなたがそれらを無制限に設定しない限り、リファレンスは記憶に残っているのだろうかと疑問に思っています。

質問2:また、あなたはその質問に答える一方で、私も別のものを持っていました。私が見たドキュメンテーションやチュートリアルクラスインスタンスだけに言及しているようです。たとえば、私がvar number = 2 var othernumber = numberを設定した場合、メモリにも "number"が格納され、すべての参照がnilになるまで割り当てが解除されます。これも当てはまる場合、同じ質問が適用されます。すべての参照をnilと同じに設定してメモリからの割り当てを解除する唯一の方法です。長い質問を申し訳ありませんが、私はメモリの概念に全く新しいです。

import UIKit 

class ViewController: UIViewController { 


var ref1: Vehicle? 
var reference2: Vehicle? 
var ref3: Vehicle? 
var timer: NSTimer! 
var count = 0 
override func viewDidLoad() { 
    super.viewDidLoad() 

    ref1 = Vehicle(kind: "Car") 
    reference2 = ref1 
    ref3 = ref1 

    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(tick), userInfo: nil, repeats: true) 


} 


func tick() { 
count++ 

    if count >= 3 { 
     ref3 = nil 
     reference2 = nil 



    } 

    if count == 5 { 
    ref1 = nil 


    } 


} 

}

class Vehicle { 

let type: String 


init(kind: String){ 
self.type = kind 
print("\(type) is being initialized") 
//when the class is instantiated, we get an initialization message. When class is deallocated, we get a deinit message. As in, all strong references are gone, we can deinitialize. 


} 
deinit { 
//class vehicle not in memory anymore as all strong references to it have been destroyed. This will be tested with segue as well. 
    print("\(type) is being deinitialized") 

}} 

答えて

3
  1. "使用" の用語で混乱/(または、せいぜい、不正確)誤解を招きます。 ARCを使用すると、明瞭でシンプルな強い参照がなくなるまでオブジェクトは解放されません。 nilこれらのすべての強力な参照、またはその強い参照が範囲外になる場合、オブジェクトが割り当て解除された時点です。

    ちなみに、scheduledTimerWithTimeIntervalは、そのターゲットへの強力な参照を確立することに注意してください。その強い参照を解決するには、invalidateタイマーが必要です。

  2. ARCは参照型(例:class)にのみ適用されます。値の型(数値型またはstruct型など)には適用されません。したがって

    は、numberを参照しない

    var number = 2 
    var othernumber = number 
    

    othernumberを検討してください。それはコピーを作る。値がnumberと同じ値になる新しいオブジェクトです。スウィフト値の型を参照型と区別するための議論については、WWDC 2015 Building Better Apps with Value Typesを参照してください。 (ちなみに、複雑な値型の背後のメモリ管理は実際には単純な値型の場合より複雑ですが、この会話ではあまり関係ありません。興味があります)

+0

どのようなシナリオでは、どのようなシナリオで「範囲外」になるのか、ありがとうと思います。 – slimboy

+0

また、私はValue型を推測していますが、それらもメモリに割り当てられ、割り当てが解除されています。プログラマはメモリ空間を確保するために自分で割り当てを解除する必要がありますか? – slimboy

+0

これをクリアしてくれてありがとう、私は今それを得る。 – slimboy

1

これは大きな質問です。

ARCを理解するには、手動で参照カウントを理解する必要があります。

参照カウントは、どのオブジェクトがまだ使用されているかを追跡する方法で、割り当てを解除することができます。

手動参照カウントでは、オブジェクトに保持カウントがあります。

オブジェクトに保持メッセージを送信して保持カウントを増やし、解放して保持カウントを減らします。オブジェクトに解放メッセージを送信すると、保持カウントが0に落ちるため、オブジェクトは解放/解放されます。

「自動解放プール」にオブジェクトを追加するautoreleaseメッセージもあります。コードが返され、イベントループが訪れるたびに、自動解放プール内のすべてのオブジェクトには、自動解放プール内にあるたびに解放メッセージが送信されます。 (オブジェクトに複数の自動解放メッセージを送ることはできますが、無視してください)。自動解放は、特別なことをしないと消えてしまう一時的なオブジェクトを返すのに便利です。オートレリースされたオブジェクトは、現在のコールチェーン中に固執しますが、誰もそれを保持していなければコードが返っても解放されます。

オブジェクトは、参照カウント1で作成され、所有者に返されます。所有者は、完了した時点でオブジェクトにリリースメッセージを送信する責任があります。

手動参照カウントでは、メモリ管理の意図を表現するために、正しい場所にコードのretain、release、およびautorelease呼び出しを配置する必要があります。間違っていると、メモリリークやクラッシュが発生します。

ARCは上記のメカニズムをすべて使用しますが、コンパイラはコードを分析し、保持、解放、および自動解放呼び出しを挿入します。また、余分な保持/解放呼び出しを最低限必要なものだけ取り除きます。

ARCでは、変数を強または弱として宣言するだけで、コンパイラは残りの処理を行います。まだいくつかの問題がありますが、ほとんどの場合、メモリ管理について心配する必要はありません。

強い変数にオブジェクトを格納すると、コンパイラは保持呼び出しを生成します。強い変数をゼロにすると、コンパイラはオブジェクトに解放メッセージを送信します。

ガベージコレクションとは異なり、システムを停止する必要はなく、メモリに時間がかかるクリーンアップが行われます。オブジェクトへの強い参照がなくなると、オブジェクトは解放されます。

関連する問題