四.GCDスレッド通信と共通関数

3339 ワード

一.GCDはスレッド間の通信を実現する

  • 需要:
  • グローバル同時キューを作成し、非同期関数を使用してサブスレッドを開き、画像
  • をダウンロードする
  • ピクチャのダウンロードが終了すると、メインスレッドのメソッドを呼び出し、ピクチャをImageViewに設定し、UI
      - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
          
          // 1.  
          dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
              
              // 2.  URL
              NSURL *url = [NSURL URLWithString:@"http://dimg06.c-ctrip.com/images/tg/161/023/909/de45d234ba8147a0ace4880a92c23994_C_640_640.jpg"];
              
              // 3.  
              NSData *data = [NSData dataWithContentsOfURL:url];
              
              // 4.  
              UIImage *image = [UIImage imageWithData:data];
              NSLog(@"%@", [NSThread currentThread]);
              
              
              // 5.  (UI ,  )
              dispatch_async(dispatch_get_main_queue(), ^{
                  NSLog(@"%@", [NSThread currentThread]);
                  self.imageView.image = image;
              });
          });
      }
    
  • をリフレッシュする.

    二.CGDの一般的な関数

  • 遅延実行タスク:Delay
  • 開発では、遅延実行
  • と呼ばれる、一つの方法をX秒遅延させてから実行する.
  • 実行を遅延する様々な方法:
  • NSRunLoopの手法を用いる、現在のスレッドではX秒を遅らせて、指定の手法[self performSelector:@selector(task) withObject:nil afterDelay:2];
  • を実行する.
  • NSTimerメソッドを使用して、現在の実行サイクルにNSTimterのインスタンスを追加し、X秒後に、指定されたメソッド[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(task) userInfo:nil repeats:NO];
  • を実行する.
  • GCDタイマを使用して、X秒後に指定されたタスクを実行します.
  • GCDは実行を遅延する、原理的にはBlockのコードを先に保存してから指定の時間を遅らせた後、Blockのコード
  • を実行する.
  • GCD遅延実行は、Blockのコードが指定するキューで
  • を実行するようにキューを設定することもできる.
  • dispatch_after自体は非同期関数であるため、キューを指定した場合、サブスレッドを使用してタスクを実行することができ、より効率的である
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
          [self task];
          NSLog(@"%@", [NSThread currentThread]);
      });
    


  • 使い捨てコード(重要!単例に多く使用!!)
  • フォーマット
      static dispatch_once_t onceToken;
      dispatch_once(&onceToken, ^{
          [self task];
      });
    
  • を使用
  • 注意点:
  • ワンタイムコードはプログラム全体で1回しか実行されず、再び呼び出されるとdispatch_once関数の内容は
  • を再実行しません.
  • リロードでこの関数を使用することはできません
  • この関数は、主に単一のオブジェクトを作成するために使用され、単一のオブジェクトがプログラム全体に1回のメモリ
  • のみを割り当てることを保証します.

  • フェンス関数
  • フェンス関数タスクを制御するための実行順序
  • 2 2 2つのタスクの間にフェンス関数を追加すると、タスクの実行順序が分離され、前のタスクの実行が終了すると、後のタスクは
  • を実行します.
  • フェンス関数は主に同時キューの制御に用いられ、タスク実行の順序
  • である.
  • シリアルキューにおいてフェンス関数を使用する必要はない.シリアルキュー自体が順次シリアル実行タスクの
  • であるからである.
  • 注意:フェンス関数はグローバル同時キューには使用できません.フェンス関数はグローバル同時実行では有効ではありません.
      // 3.  
      - (void)barrier {
          
          // 1.  
          dispatch_queue_t queue = dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT);
          
          // 2.  
          dispatch_async(queue, ^{
              [self task];
          });
          
          dispatch_async(queue, ^{
              [self task];
          });
          
          // 3.  
          dispatch_barrier_async(queue, ^{
              NSLog(@"-----------------");
          });
          
          dispatch_async(queue, ^{
              [self task];
          });
          
          dispatch_async(queue, ^{
              [self task];
          });
          
          dispatch_async(queue, ^{
              [self task];
          });
      }