iOSマルチスレッド--NSOperation

6630 ワード

概要NSOperationNSOperationQueueはアップルが提供したマルチスレッドソリューションであり、GCDより高い層のパッケージに基づいて、完全にオブジェクトに向いている.しかし、GCDよりも簡単で使いやすく、コードの可読性が高い.
  • の利点:完了したコードブロックcompleteを追加し、操作が完了した後に実行することができる.操作間の依存関係を追加し、実行順序の制御を容易にします.操作実行の優先度を設定します.操作の実行をキャンセルできます.実行状態をKVOで観察する:isExecuteing、isFinished、isCancelled.
  • NSOperation、NSOperationQueueにも同様の「タスク」と「キュー」の概念がある.
    1.NSOperation
    タスク、または操作.すなわち、スレッドで実行されるコードです.NSOperationは、そのサブクラスNSInvocationOperation、NSBlockOperationまたはカスタムサブクラスを使用してタスクをカプセル化する抽象クラスである.
    2.NSOperationQueue
    オペレーションを格納するためのキューを指します.
  • キュータイププライマリ・キュー、カスタム・キュー.プライマリ・キュー列はプライマリ・スレッドの上で実行され、カスタム・キューはバックグラウンドで実行されます.
  • タスクのステータスと順序は、GCDのキューFIFO(先進先出)の原則とは異なります.NSOperationQueueに追加されたタスクについては、まず準備完了の状態(準備完了の順序ではなく、タスク間の依存関係に依存)に入り、次に準備完了の状態に入ったタスクの開始実行順序(実行完了の順序)は、タスク間の相対的な優先度によって決定される.
  • コンカレントおよびシリアルタスクキューは、最大コンカレントオペランドmaxConcurrentOperationCountを設定することによって、コンカレント、シリアルを制御する.

  • 3.NSOperationマルチスレッド実装
    デフォルトでは、NSOperationが単独で使用されている場合、システムは同期して動作します.NSOperationQueueを組み合わせてこそ、非同期実行をよりよく実現することができる.
  • は、ステップを使用して3つのステップに分けてタスクを作成します.まず、実行する必要があるタスクをNSOperationオブジェクトにカプセル化します.キューの作成:NSOperationQueueオブジェクトです.タスクをキューに追加:NSOperationオブジェクトをNSOperationQueueオブジェクトに追加します.

  • システムは、NSOperationQueueNSOperationを自動的に取り出し、新しいスレッドで操作を実行します.
    3.1 NSOperationタスクの作成NSOperationは抽象クラスであり、タスクをカプセル化するために直接使用することはできません.タスクをカプセル化するには、そのサブクラスを使用します:NSInvocationOperation、NSBlockOperationおよびカスタムサブクラス.
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
    [op start];   //     
    
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            //  do some thing...
    }]; 
    [op start];
    

    さらに、タスクオブジェクトに追加のタスクを追加できます.
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        // do something...
    }];
    
    //        
    [op addExecutionBlock:^{
        // do otherthing...
    }]; 
    
  • は、NSOperationQueueを使用せず、メインスレッドでNSOperationのサブクラスオブジェクトを単独で使用して1つのタスクを実行した場合、タスクは現在のスレッドで実行され、新しいスレッドは開かれません.
  • サブクラスNSBlockOperationを使用し、メソッドaddExecutionBlock:を呼び出す場合、追加された操作の個数が多ければ、自動的に新しいスレッドが開きます.

  • 2.NSOperationQueueの作成
    プライマリ・キュー、カスタム・キューの2種類があります.
  • ホームチーム
  • NSOperationQueue *queue = [NSOperationQueue mainQueue];
    

    プライマリ・キュー・カラムに追加された操作は、プライマリ・スレッドに格納されます.
  • カスタムキューがこのキューに追加されると、サブスレッドに自動的に配置されて実行されます.シリアル、同時機能も含まれています.
  • NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    queue. maxConcurrentOperationCount = 3;
    

    属性maxConcurrentOperationCountの最大同時操作数を設定し、シリアル、同時を決定することができる.
    属性maxConcurrentOperationCount=1;//シリアルキュー、タスクは順番にシリアルでしか実行できません=2;//同時キュー、>2の場合、タスクは同時実行され、複数の操作を同時に実行できます=8;//コンカレントキューはもちろん、この値はシステムの制限を超えてはいけません.大きな値を設定しても、システムは自動的にminに調整されます.
    3.キューにアクションを追加
    方法addOperation:
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
        NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
     
        NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
            //.....
        }];
        [op3 addExecutionBlock:^{
            //.....
        }];
    
        [queue addOperation:op1];  
        [queue addOperation:op3];  
    

    方法addOperationWithBlock:
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        //         
        [queue addOperationWithBlock:^{
            //.....
        }];
    

    操作と操作キュー、使用手順と基本的な使用方法、シリアル/同時実行の制御、
    NSOperation依存
    依存することで,タスク間の実行順序を容易に制御できる.addDependency:(NSOperation *)op;依存を追加removeDependency:(NSOperation *)op;依存を削除NSArray *dependencies;現在のタスクが実行される前に完了したタスクオブジェクトの配列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
     
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
            //.....
        }];
        NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
            //.....
        }];
    
        //     
        [op2 addDependency:op1]; // op2     op1。     op1
    
        [queue addOperation:op1];
        [queue addOperation:op2];
    
  • 準備完了ステータスタスクのすべての依存が完了すると、タスクオブジェクトは通常準備完了ステータスに入り、実行を待機します.

  • NSOperation優先度NSOperationは、優先度属性queuePriorityを提供する.デフォルトでは、新しく作成されたすべての操作オブジェクトの優先度はNSOperationQueuePriorityNormalです.しかし、setQueuePriority:の方法によって、同じキュー内のタスクの優先度を変更することができる.queuePriorityプロパティは、同じキュー内のタスクに適用され、異なるキューのタスクは適用されません.優先度の値:NSOperationQueuePriorityVeryLow = -8L, NSOperationQueuePriorityLow = -4L, NSOperationQueuePriorityNormal = 0,(デフォルト)NSOperationQueuePriorityHigh = 4, NSOperationQueuePriorityVeryHigh = 8優先度と依存度
  • 優先度属性queuePriorityは、準備完了状態にあるタスク間の を決定する.また,優先度は依存関係に取って代わることはできない.
  • キューに優先度の高いタスクと優先度の低いタスクが含まれ、両方のタスクが準備されている場合、キューはまず優先度の高いタスクを実行します.
  • 優先度は依存関係に取って代わることはできません.1つのキューに準備完了ステータスのタスクAと、準備完了していないタスクBが含まれている場合、Bの優先度はAより高い.では、Bを優先的に実行します.操作間の起動順序を制御する場合は、依存関係を使用する必要があります.

  • スレッド間の通信
    サブストロークの処理を完了し、メインストローク処理に戻る
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
     
        [queue addOperationWithBlock:^{
            // .....
    
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                //      ,       UI      
            }];
        }];
    

    スレッド同期とスレッドセキュリティ
  • スレッドセキュリティ複数のスレッドが同時にコードを実行する可能性があります.各実行結果が単一スレッドで実行された結果と同じであり、他の変数の値も予想通りであれば、スレッドは安全です.各スレッドでグローバル変数、静的変数に対して読み取り操作(書き込み操作なし)しかない場合、一般的にこの変数はスレッドが安全である.複数のスレッドが同時に書き込み操作(変数の値を変更)を実行している場合は、スレッドの同期を考慮する必要があります.そうしないと、スレッドのセキュリティに影響を与える可能性があります.
  • スレッド同期は、スレッドAとスレッドBが一緒に結合していると理解され、Aがある程度実行されると、スレッドBの結果に依存しなければならないので、停止し、Bの実行を示す.Bは言うとおりに実行し、結果をAに与える.A操作を続行します.例:列車の切符販売
  • スレッドセキュリティソリューションは、1つのスレッドがこの操作を実行するときに、他のスレッドが操作することを許可しないスレッドにロックをかけることができます.

  • iOS実装スレッドのロックには、NSLock、@synchronized、NSRecursiveLock、NSCondition、NSConditionLock、pthread_など、さまざまな方法があります.mutex、dispatch_semaphore、OSSpinLock、atomic(property)set/getなど様々な方法があります.
    思想:書き込み操作を実行する前に、鍵をかけ、書き込み操作を完了し、ロックを解除します.
    NSOperation、NSOperationQueueの共通属性とメソッドのまとめ.