iOS-NSThread/NSOperation/GCDの3種類のマルチスレッド技術の比較と実現

11672 ワード


 

1.iOSの3種類のマルチスレッド技術


1.NSThread各NSThreadオブジェクトは1つのスレッドに対応し、軽量(真のマルチスレッド)
2.次の2つの点は、アップルが開発した「同時」技術であり、プログラマーがスレッドの具体的な使用問題に関心を持たなくてもよい.
ØNSOperation/NSOperationQueueオブジェクト向けスレッド技術
ØGCD-Grand Central Dispatch(配布)はC言語ベースのフレームワークで、マルチコアを活用することができ、アップルが推奨するマルチスレッド技術です
 
以上の3つのプログラミング方式は上から下へ、抽象度階層は低から高へ、抽象度が高いほど使用が簡単で、Appleが最も推奨しているもので、プロジェクトでは多くのフレームワーク技術が異なるマルチスレッド技術を使用しています.
 

2. 3つのマルチスレッド技術の比較


•NSThread:
-利点:NSThreadは他の2つの軽量レベルよりも使いやすい
-欠点:スレッドのライフサイクル、スレッドの同期、ロック、スリープ、目覚ましなどを自分で管理する必要があります.スレッド同期によるデータのロックには、システムオーバーヘッドが発生します.
 
•NSOperation:
–スレッド管理、データ同期に関心を持たず、必要な操作に集中
-NSOperationはオブジェクト向け
 
•GCD:
-Grand Central Dispatchはアップルが開発したマルチコアプログラミングのソリューションです.iOS4.0+を使用することができ、NSThread、NSOperationに代わる効率的で強力なテクノロジーです.
–GCDはC言語ベース

 


3.三種類のマルチスレッド技術の実現


3.1. NSThreadのマルチスレッド技術、


 
1>クラスメソッドバックグラウンドスレッドを直接開き、セレクタメソッドを実行
    detachNewThreadSelector
  
1  //  , @selector 
2 
3 [NSThread detachNewThreadSelector:@selector(bigDemo) toTarget:self withObject:nil];

 
 
 
2>メンバーメソッドです.スレッドオブジェクトをインスタンス化した後、startを使用してセレクタメソッドを実行する必要があります.
    initWithTarget
 
   //  
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(bigDemo) object:nil];
    
    //  start 
    [thread start];

 
 
 
 
 
NSThreadの簡単な使用はNSObjectのperformSelectorInBackgroundで代用できます
 
1   // performSelectorInBackground bigDemo 
2 
3     [self performSelectorInBackground:@selector(bigDemo) withObject:nil];

 
また、NSThread呼び出しのメソッドでもautoreleasepoolを使用してメモリ管理を行う必要があります.そうしないと、メモリ漏洩が発生しやすくなります.
 1   //  
 2 
 3     //  , NSThread NSObject , 
 4 
 5     //
 6 
 7     @autoreleasepool {
 8 
 9 
10 
11   }

 
 

3.2 NSOperation、オブジェクト向けマルチスレッド技術


 
1>使用手順:
1)インスタンス化操作
 
1     //  
2     _queue = [[NSOperationQueue alloc] init];

 
 
        a) NSInvocationOperation
1     NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(opAction) object:nil];
2     
3     //  start, 
4 //    [op1 start];
5     
6     // 1.  , 
7     [_queue addOperation:op1];

 
    
        b) NSBlockOperation
 1 #pragma mark  
 2 - (IBAction)operationDemo3:(id)sender
 3 {
 4     // 1.  
 5     NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
 6         NSLog(@"  %@" , [NSThread currentThread]);
 7     }];
 8     // 2.  
 9     NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
10         NSLog(@"  %@" , [NSThread currentThread]);
11     }];
12     // 3.  
13     NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
14         NSLog(@" UI %@" , [NSThread currentThread]);
15     }];
16     
17     //  , “ ” , , 
18     //  
19     //  : , , 。
20     [op2 addDependency:op1];
21     [op3 addDependency:op2];
22 //    [op1 addDependency:op3];
23     
24     [_queue addOperation:op1];
25     [_queue addOperation:op2];
26     [[NSOperationQueue mainQueue] addOperation:op3];
27 }

 
 
2)キューNSOperationQueueに操作を追加するとマルチスレッド実行が開始される
 
1    [_queue addOperation:op1];
2    [_queue addOperation:op2];

 
2>UIの更新メインスレッドキューの使用
 
    // 

    [NSOpeationQueue mainQueue] addOperation ^{



  };


    [[NSOperationQueue mainQueue] addOperation:op3];

 
 
3>操作キューのsetMaxConcurrentOperationCount
同時実行スレッド数を設定できます!
1     //  
2     [_queue setMaxConcurrentOperationCount:2];

 
ヒント:この機能はNSOperationのみ!
 
4>addDependencyを使用すると、タスクの実行順序を設定できます.また、操作キュー間で依存関係を指定できます.
   
1      //  , “ ” , , 
2 
3    //  
4 
5     //  : , , 。
6   [op2 addDependency:op1];
7   [op3 addDependency:op2];
8   [op1 addDependency:op3];

 
ヒント:依存関係を指定するときは、依存をループしないように注意してください.そうしないと、動作しません.
 
 

3.3. GCD,C言語


 


GCDは「マルチコア」でマルチスレッド技術を使うため
 
1>GCDを使うには、すべての方法がdispatchで始まる
2>名詞解釈
グローバルグローバル
Queueキュー
async非同期
sync同期
 
3>非同期のタスクを実行するには、グローバルキューで実行します.
 dispatch_async非同期実行制御は前後順序に耐えられない
 
4>GCDのキューについて
グローバルキューdispatch_get_global_queue
パラメータ:優先度DISPATCH_QUEUE_PRIORITY_DEFAULT
常に0
1  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

同期可能非同期
     
シリアルキュー
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

 
作成されたもので、直接取得できません.
同期のみ
 
 
プライマリ・キューdispatch_get_main_queue
1 dispatch_async(dispatch_get_main_queue(), ^{
2         NSLog(@"main - > %@", [NSThread currentThread]);
3     });

歩み寄るしかない
 
 
5>非同期と同期はメソッド名に関係なく、実行中のキューに関係します.
同期は主にメソッドの呼び出された順序を制御するために使用されます.
 
 
 
澄みきったSaup