Objective-Cメモリ管理、blockとGCD

4606 ワード

メモリ管理
  • 参照カウント:参照カウントテーブルメンテナンスオブジェクトの参照数
  • autorelease:最内層のAutoReleasePoolオブジェクトリストに追加し、AutoReleasePoolを破棄するとリスト内のオブジェクト
  • を解放します.
  • alloc/new/copy/mutableCopyが開始しないメソッドで返されるオブジェクトは、自動的にautoreleasepoolに登録されますが、返される値が強く適用されると、コンパイラはautoreleasepoolに登録する必要がないように最適化されます.
  • オブジェクトポインタのポインタ、デフォルトでは_autorealeaseは、原則として自分で作成しないオブジェクトは自分で持つべきではないからです.NSError**のようにNSError*_に等しいautorelease *
  • ARC使用規則
  • retain/release/retainCount/autorelease
  • は使用できません.
  • NSAllocateObject/NSSDeallocateObject
  • は使用できません.
  • メモリ管理方法の命名規則
  • を遵守する必要があります.
    alloc/new/copy/mutableCopyの先頭のメソッドは、オブジェクトinitの先頭を返すメソッドがより厳しく、インスタンスメソッドでなければなりません.返されるオブジェクトはid、存在するクラス、そのクラスのスーパークラス、またはサブクラスでなければなりません.返されたオブジェクトはautoreleasepoolに登録されません.
  • 呼び出しdealloc
  • を表示しないでください.
  • NSReleasePoolの代わりに@autoreleasepoolを使用
    MRCも@autoreleasepoolで
  • NSZone
  • は使用できません
    MRCも使わないで、実はシステムは無視します
  • オブジェクト変数はC言語構造体メンバー
  • として使用できません.
    C言語では構造体上のメンバーのライフサイクルを管理できない
  • 変換idとvoid*
  • を表示する必要があります.
    __bridge変換、所有権の変換は発生しません_bridge_retained,変換後の変数もオブジェクトを持つ_bridge_Transferは、変換された変数が持つオブジェクトにターゲット変数を付与した後、Core Foundationに対応する変換CFBridgingRetain/FBridgingReleaseを解放する
    void *p = (__bridge_retained void *) obj;
    id obj = (__bridge_transfer id) p;
    
  • プロパティ@property assign/copy/retain/strong/unsafe_unretained/weak

  • ライフクラスメンバー変数の場合、属性宣言と異なる場合にコンパイルエラーが発生します.もちろん、クラスメンバー変数を手動で書き込む必要はありません.一般的には@propertyで自動的に生成されます.
  • ARCは1を実現する.strongは,役割ドメイン終了時にrelease,alloc/init/copyメソッド以外のオブジェクトに対して,本来objc_autoreleaseReturnValue(obj)はautoreleasepoolに登録されていますが、strongによって参照されるとobjc_が呼び出されます.retainAutorealseReturnValue(obj)がオブジェクトを参照すると、コンパイラはautoreleasepoolに追加する必要がないと判断します.
  • weakは、オブジェクトを参照するときにweakテーブルに記録され、オブジェクトが解放されると、バーweakテーブルのオブジェクトを指す変数が空になります.Weak変数を使用すると自動的に一時変数が生成され、オブジェクトがautorealeasepoolに追加されます.
  • id __weak o = obj;
    NSLog(@"1 %@", obj);   //  
    NSLog(@"2 %@", obj);   //  
    
    //  autoreleasepool
    id __weak o = obj;
    id tmp = o;
    NSLog(@"1 %@", tmp);  
    NSLog(@"2 %@", tmp);   
    

    3、autorealease、MRCに相当する手動呼び出しautorealease方法
    Blocks
    BlocksはC言語の拡張機能である:自動変数付き匿名関数.書式:
    ^int (int count) {return count + 1;}  //  
    ^(int count) {printf("%d", count)} //  
    ^{printf("test")} //  
    // block 
    typedef int (^blk_t) (int);
    
  • 自動変数
  • をキャプチャ
    通常変数の値が切り取られていない場合の値は、変更できません.block変数はblock修正値でキャプチャ配列をサポートせず、必要に応じてポインタに変換できます.
  • blockの実装
  • blockは実質的にObjective-Cを生成するオブジェクトであり、キャプチャされた自動変数はオブジェクトに保存されます.ブロック変数が生成されます_Block_byrefer_val構造体、blockに格納され、その中の__を通過するforwardingは実際の変数に間接的にアクセスし、blockがスタックにコピーされた場合、スタック上の_block変数もスタックにコピーされます.
  • には3つの領域のblockグローバルBlockがあります.グローバル変数で定義されている場合、またはBlockが自動変数をキャプチャする必要がない場合、スタックBlock:グローバルBlockを除いて、定義時のデフォルトはスタックBlockスタックBlock:Blockが関数の戻り値として使用されている場合、スタックにコピーされ、copyメソッドを使用してスタックにコピーされ、Blockをstrongタイプの変数に付与されている場合、またはBlockタイプのメンバー変数に付与されている場合、スタックにコピーされます.

  • メソッドにBlockを渡すと自動的にスタックにコピーされません.次の2つの方法を除きます.
  • CocoaフレームワークにおけるusingBlockの代用方法
  • GCDのAPIはグローバルBlockに対してcopyを行って何の作用もありません
  • blockループアプリケーション
  • 通過_Weak解決
  • MRC通過_blockは解決しますが、Blockが実行された後に空にする必要があります.空にすると解放されます.なぜならblockが指すオブジェクトがスタックにコピーされるとretainされません.

  • GCD
  • の2つのキュー:Serial DispatchQueueとConcurrent Dispatch Queue
  • Serial Dispatch Queueが生成されて使用されると、新しいスレッドが作成されます.マルチスレッドDispatch Queueが自分でreleaseしなければならないことを防止し、create以外のメソッドで返されるqueueに対してretainします.
  • dispatch_set_target_queue
  • キューの実行優先度を変更する
  • .
  • ターゲットキューは、元のキューの実行階層(複数のqueueがあるtargetに設定された場合)
  • とすることができる.
  • dispatch_after

  • 指定した時間後に実行するのではなく、指定した時間後にqueueに追加するのです
  • Dispatch Group

  • 複数の処理をすべて実行してから、他の処理を実行する場合に使用します.
  • dispatch_barrier_async

  • barrier関数の前にあるすべての操作が実行されるのを待って、barrier関数が実行されると、barrier関数の後にある操作が実行されます.
  • dispatch_async

  • 処理実行が終了するまで、関数は返されません.デッドロックの問題に注意:
    dispatch_queue_t queue dispatch_get_main_queue();
    dispatch_async(queue, ^{
            dispatch_sync(queue, ^{});
    })
    
  • dispatch_apply

  • 指定した回数でblockを指定したqueueに追加し、処理が完了するのを待つ.
  • dispatch_suspend/dispatch_resume

  • 実行された処理に対してqueueを一時停止またはリカバリします.処理された処理または処理中の処理には影響しません.
  • Dispatch Semaphore

  • 信号量,waitメソッドカウントが0未満の場合は待機し,カウント>=1の場合は待機せずに1を減算する.Signalメソッドプラス1
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2); //  2 
    dispatch_semaphore_wait(semaphore, time); //  -1
    dispatch_semaphore_signal(semaphore); //  +1
    
    
  • dispatch_once

  • アプリケーションの実行中に1回だけ処理が実行されることを保証します.