GCD

GCD的基礎知識html

 

 

 

同步函數+串行隊列ios

//同步函數 + 串行隊列
- (void)syncSerial {
    
    NSLog(@"start %s -------%@",__FUNCTION__,[NSThread currentThread]);
    /* 建立串行隊列 */
    dispatch_queue_t queue = dispatch_queue_create("https://teilim.com", DISPATCH_QUEUE_SERIAL);
    
    /* 將執行任務加入隊列 */
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
            NSLog(@"task A time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
            NSLog(@"task B time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    NSLog(@"finish %s -------%@",__FUNCTION__,[NSThread currentThread]);

}

打印內容網絡

2016-11-11 20:16:47.338 MutipleThreadPractice[27817:3509801] start -[GCDDemoViewController syncSerial] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.339 MutipleThreadPractice[27817:3509801] task A time 0 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.339 MutipleThreadPractice[27817:3509801] task A time 1 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task A time 2 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task A time 3 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task A time 4 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task B time 0 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task B time 1 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task B time 2 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task B time 3 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] task B time 4 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:16:47.340 MutipleThreadPractice[27817:3509801] finish -[GCDDemoViewController syncSerial] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}

 

同步函數+併發隊列session

//同步函數 + 併發隊列
- (void)syncConcurrent {
    
    NSLog(@"start %s -------%@",__FUNCTION__,[NSThread currentThread]);
    /* 建立併發隊列 */
    dispatch_queue_t queue = dispatch_queue_create("https://teilim.com", DISPATCH_QUEUE_CONCURRENT);
    
    /* 將執行任務加入隊列 */
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
                NSLog(@"task A time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
              NSLog(@"task B time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    NSLog(@"finish %s -------%@",__FUNCTION__,[NSThread currentThread]);
}

 

打印內容併發

2016-11-11 20:19:35.113 MutipleThreadPractice[27817:3509801] start -[GCDDemoViewController syncConcurrent] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.113 MutipleThreadPractice[27817:3509801] task A time 0 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.114 MutipleThreadPractice[27817:3509801] task A time 1 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.114 MutipleThreadPractice[27817:3509801] task A time 2 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.114 MutipleThreadPractice[27817:3509801] task A time 3 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.115 MutipleThreadPractice[27817:3509801] task A time 4 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.115 MutipleThreadPractice[27817:3509801] task B time 0 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.115 MutipleThreadPractice[27817:3509801] task B time 1 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.117 MutipleThreadPractice[27817:3509801] task B time 2 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.117 MutipleThreadPractice[27817:3509801] task B time 3 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.117 MutipleThreadPractice[27817:3509801] task B time 4 -----<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:19:35.118 MutipleThreadPractice[27817:3509801] finish -[GCDDemoViewController syncConcurrent] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}

 

異步函數+串行隊列app

//異步函數 + 串行隊列
- (void)asyncSerial {
    
    NSLog(@"start %s -------%@",__FUNCTION__,[NSThread currentThread]);
    
    /* 建立串行隊列 */
    dispatch_queue_t queue = dispatch_queue_create("https://teilim.com", DISPATCH_QUEUE_SERIAL);
    
    /* 將任務加入隊列 */
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
            NSLog(@"task A time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
              NSLog(@"task B time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    
    NSLog(@"finish %s -------%@",__FUNCTION__,[NSThread currentThread]);

}

 

打印內容異步

2016-11-11 20:20:58.620 MutipleThreadPractice[27817:3509801] start -[GCDDemoViewController asyncSerial] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:20:58.621 MutipleThreadPractice[27817:3509801] finish -[GCDDemoViewController asyncSerial] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:20:58.621 MutipleThreadPractice[27817:3515050] task A time 0 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.622 MutipleThreadPractice[27817:3515050] task A time 1 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.623 MutipleThreadPractice[27817:3515050] task A time 2 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.624 MutipleThreadPractice[27817:3515050] task A time 3 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.626 MutipleThreadPractice[27817:3515050] task A time 4 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.626 MutipleThreadPractice[27817:3515050] task B time 0 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.627 MutipleThreadPractice[27817:3515050] task B time 1 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.627 MutipleThreadPractice[27817:3515050] task B time 2 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.627 MutipleThreadPractice[27817:3515050] task B time 3 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}
2016-11-11 20:20:58.628 MutipleThreadPractice[27817:3515050] task B time 4 -----<NSThread: 0x7ff2a86bba20>{number = 2, name = (null)}

 

 

異步函數+併發隊列async

//異步函數 + 串行隊列
- (void)asyncSerial {
    
    NSLog(@"start %s -------%@",__FUNCTION__,[NSThread currentThread]);
    
    /* 建立串行隊列 */
    dispatch_queue_t queue = dispatch_queue_create("https://teilim.com", DISPATCH_QUEUE_SERIAL);
    
    /* 將任務加入隊列 */
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
            NSLog(@"task A time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<5; i++) {
              NSLog(@"task B time %lo -----%@", i,[NSThread currentThread]);
        }
    });
    
    NSLog(@"finish %s -------%@",__FUNCTION__,[NSThread currentThread]);

}

 

 

打印內容函數

2016-11-11 20:22:17.234 MutipleThreadPractice[27817:3509801] start -[GCDDemoViewController asyncConcurrent] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:22:17.234 MutipleThreadPractice[27817:3509801] finish -[GCDDemoViewController asyncConcurrent] -------<NSThread: 0x7ff2a8501790>{number = 1, name = main}
2016-11-11 20:22:17.234 MutipleThreadPractice[27817:3516618] task A time 0 -----<NSThread: 0x7ff2a8476df0>{number = 3, name = (null)}
2016-11-11 20:22:17.234 MutipleThreadPractice[27817:3516625] task B time 0 -----<NSThread: 0x7ff2a870f6a0>{number = 4, name = (null)}
2016-11-11 20:22:17.236 MutipleThreadPractice[27817:3516618] task A time 1 -----<NSThread: 0x7ff2a8476df0>{number = 3, name = (null)}
2016-11-11 20:22:17.236 MutipleThreadPractice[27817:3516625] task B time 1 -----<NSThread: 0x7ff2a870f6a0>{number = 4, name = (null)}
2016-11-11 20:22:17.237 MutipleThreadPractice[27817:3516618] task A time 2 -----<NSThread: 0x7ff2a8476df0>{number = 3, name = (null)}
2016-11-11 20:22:17.237 MutipleThreadPractice[27817:3516625] task B time 2 -----<NSThread: 0x7ff2a870f6a0>{number = 4, name = (null)}
2016-11-11 20:22:17.238 MutipleThreadPractice[27817:3516618] task A time 3 -----<NSThread: 0x7ff2a8476df0>{number = 3, name = (null)}
2016-11-11 20:22:17.239 MutipleThreadPractice[27817:3516625] task B time 3 -----<NSThread: 0x7ff2a870f6a0>{number = 4, name = (null)}
2016-11-11 20:22:17.239 MutipleThreadPractice[27817:3516618] task A time 4 -----<NSThread: 0x7ff2a8476df0>{number = 3, name = (null)}
2016-11-11 20:22:17.239 MutipleThreadPractice[27817:3516625] task B time 4 -----<NSThread: 0x7ff2a870f6a0>{number = 4, name = (null)}

 

GCD groupatom

dispatch_group_notify函數用來指定一個額外的block,該block將在group中全部任務完成後執行

-(void)gcdGroup{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        
        [NSThread sleepForTimeInterval:5];
        
        NSLog(@"finish task 1");
        /*加載圖片1 */ });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:1];
        
        NSLog(@"finish task 2");
        /*加載圖片2 */ });
    
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"finish task 3");
        /*加載圖片3 */ });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"do next step after all the tasks ");
        // 合併圖片
    });



}

打印內容

2016-11-11 20:24:04.883 MutipleThreadPractice[27817:3518196] finish task 2
2016-11-11 20:24:05.883 MutipleThreadPractice[27817:3518197] finish task 3
2016-11-11 20:24:08.887 MutipleThreadPractice[27817:3518158] finish task 1
2016-11-11 20:24:08.887 MutipleThreadPractice[27817:3509801] do next step after all the tasks

 

 

GCD Barrier

-(void)gcdBarrier{
    dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"dispatch-1");
    });
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"dispatch-2");
    });
    dispatch_barrier_async(concurrentQueue, ^(){
        NSLog(@"dispatch-barrier");
    });
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"dispatch-3");
    });
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"dispatch-4");
    });


}

打印

2016-11-11 20:25:31.036 MutipleThreadPractice[27817:3519239] dispatch-1
2016-11-11 20:25:31.036 MutipleThreadPractice[27817:3519324] dispatch-2
2016-11-11 20:25:31.037 MutipleThreadPractice[27817:3519324] dispatch-barrier
2016-11-11 20:25:31.038 MutipleThreadPractice[27817:3519324] dispatch-3
2016-11-11 20:25:31.038 MutipleThreadPractice[27817:3519239] dispatch-4


 

 

子線程進行下載圖片,完成後在主線程進行UI操做

-(void)backgroundDownloadImage{
    
 
    NSLog(@"before download image");
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSURL * url = [NSURL
                       URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];
        NSData * data = [[NSData alloc]initWithContentsOfURL:url];
        UIImage *image = [[UIImage alloc]initWithData:data];
        if (data != nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imageView.image = image;
                NSLog(@"download the image data");
            });
        }
    });
    
    NSLog(@"end download image");

}

 

打印內容

2016-11-11 20:27:00.944 MutipleThreadPractice[27817:3509801] before download image
2016-11-11 20:27:00.945 MutipleThreadPractice[27817:3509801] end download image
2016-11-11 20:27:01.359 MutipleThreadPractice[27817:3509801] download the image data

 

 

多窗口賣票模型

@interface GCDDemoViewController ()

/*庫存的火車票*/
@property (nonatomic,assign) NSInteger numberOfTickets;
/**帳戶餘額*/
@property (nonatomic,assign) float accountBalance;

@property (nonatomic,strong) dispatch_queue_t sellTicketQueue;

@implementation GCDDemoViewController
-(dispatch_queue_t)sellTicketQueue{
    if (!_sellTicketQueue) {
        _sellTicketQueue=dispatch_queue_create("SellTicketQueue", DISPATCH_QUEUE_SERIAL);
    }
    return _sellTicketQueue;

}


- (void)sellTicket:(NSInteger)number {
  self.numberOfTickets = self.numberOfTickets - 1;
  self.accountBalance = self.accountBalance + 10;
  NSLog(@"window == %ld ticket number==%ld balance=%.2f total value=%f", number,
        (long)self.numberOfTickets, self.accountBalance,
        self.numberOfTickets * 10 + self.accountBalance);
}

- (void)sellTicketsWithoutLock {

  dispatch_queue_t queue1 =
      dispatch_queue_create("com.sellTicket", DISPATCH_QUEUE_CONCURRENT);

  dispatch_async(queue1, ^{
    for (int i = 0; i < 1000; i++) {
      [NSThread sleepForTimeInterval:0.001];
      [self sellTicket:1];
    }
  });

  dispatch_async(queue1, ^{
    for (int i = 0; i < 1000; i++) {
      [NSThread sleepForTimeInterval:0.002];
      [self sellTicket:2];
    }
  });
  dispatch_async(queue1, ^{
    for (int i = 0; i < 1000; i++) {
      [self sellTicket:3];
      [NSThread sleepForTimeInterval:0.004];
    }
  });
}

 

 

加鎖對競爭性資源的讀寫進行限制

- (void)sellTicketsWithLock {

  dispatch_queue_t queue1 =
      dispatch_queue_create("com.sellTicket", DISPATCH_QUEUE_CONCURRENT);

  dispatch_async(queue1, ^{

    for (int i = 0; i < 1000; i++) {
      @synchronized(self) {
        [NSThread sleepForTimeInterval:0.001];
        [self sellTicket:1];
      }
    }
  });

  dispatch_async(queue1, ^{

    for (int i = 0; i < 1000; i++) {
      @synchronized(self) {
        [NSThread sleepForTimeInterval:0.002];
        [self sellTicket:2];
      }
    }
  });
  dispatch_async(queue1, ^{

    for (int i = 0; i < 1000; i++) {
      @synchronized(self) {
        [NSThread sleepForTimeInterval:0.004];
        [self sellTicket:3];
      }
    }
  });
}

 

 

使用串行隊列進行限制

- (void)sellTicketsWithSerialQueue {
  dispatch_queue_t queue1 =
      dispatch_queue_create("com.sellTicket", DISPATCH_QUEUE_CONCURRENT);
  for (int i = 0; i < 1000; i++) {
    dispatch_async(queue1, ^{
      [NSThread sleepForTimeInterval:0.001];
      [self sellTicketInSerialQueue];
    });

    dispatch_async(queue1, ^{
      [NSThread sleepForTimeInterval:0.002];
      [self sellTicketInSerialQueue];
    });

    dispatch_async(queue1, ^{
      [NSThread sleepForTimeInterval:0.004];
      [self sellTicketInSerialQueue];
    });
  }
}

- (void)sellTicketInSerialQueue {
  dispatch_async(self.sellTicketQueue, ^{
    self.numberOfTickets = self.numberOfTickets - 1;
    self.accountBalance = self.accountBalance + 10;
    NSLog(@"  ticket number==%ld balance=%.2f total value=%f",
          (long)self.numberOfTickets, self.accountBalance,
          self.numberOfTickets * 10 + self.accountBalance);

  });
}

 

 

信號量

 

常見業務場景,

1,多個網絡請求返回之後同時作處理

 

在異步執行的代碼中,只有當信號量>0時才能繼續執行。這樣能夠控制最大併發的數量。也能夠作異步任務的同步處理。

 

/建立信號量/
            dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
            /建立全局並行/
            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            dispatch_group_t group = dispatch_group_create();
            dispatch_group_async(group, queue, ^{
                NSLog(@"處理事件A");
                for (int i = 0; i<10000; i++) {
                    NSLog(@"打印i %d",i);
                }
                dispatch_semaphore_signal(semaphore);
            });
            dispatch_group_async(group, queue, ^{
                NSLog(@"處理事件B");
                for (int i = 0; i<10000; i++) {
                    NSLog(@"打印j %d",i);
                }
                dispatch_semaphore_signal(semaphore);
            });
            dispatch_group_async(group, queue, ^{
                NSLog(@"處理事件C");
                for (int i = 0; i<10000; i++) {
                    NSLog(@"打印k %d",i);
                }
                dispatch_semaphore_signal(semaphore);
            });
            dispatch_group_async(group, queue, ^{
                NSLog(@"處理事件D");
                for (int i = 0; i<10000; i++) {
                    NSLog(@"打印l %d",i);
                }
                dispatch_semaphore_signal(semaphore);
            });

            dispatch_group_notify(group, queue, ^{
                     /四個請求對應四次信號等待/
                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                    NSLog(@"處理事件E");
            });

 

 

這個例子,控制了,最大的併發線程數是10.超過10個線程執行的話,就暫時中止加入新的任務。

// 建立隊列組
    dispatch_group_t group = dispatch_group_create();   
// 建立信號量,而且設置值爲10
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);   
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
    for (int i = 0; i < 100; i++)   
    {   // 因爲是異步執行的,因此每次循環Block裏面的dispatch_semaphore_signal根本尚未執行就會執行dispatch_semaphore_wait,從而semaphore-1.當循環10此後,semaphore等於0,則會阻塞線程,直到執行了Block的dispatch_semaphore_signal 纔會繼續執行
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);   
        dispatch_group_async(group, queue, ^{   
            NSLog(@"%i",i);   
            sleep(2);   
// 每次發送信號則semaphore會+1,
            dispatch_semaphore_signal(semaphore);   
        });   
    }

 

屢次請求之後綜合處理

 

- (dispatch_queue_t)uploadImageConcurrentQueue {
  if (!_uploadImageConcurrentQueue) {
    _uploadImageConcurrentQueue = dispatch_queue_create(
        "com.hzt.uploadImageQueue", DISPATCH_QUEUE_CONCURRENT);
  }
  return _uploadImageConcurrentQueue;
}

- (void)multipleOperationDemo {

  //併發下載多張圖片,而後對全部的圖片完成後。好處在於能夠對更多的操做
  NSArray *imageURLs = @[
    @"http://zbimg.25pp.com/images/artwork/102/951610982_54x54.jpg",
    @"http://zbimg.25pp.com/images/artwork/92/855031900_54x54.jpg",
    @"http://zbimg.25pp.com/images/artwork/246/950137846_54x54.jpg"
  ];

  dispatch_async(self.uploadImageConcurrentQueue, ^{
    // 建立信號量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    // 建立全局並行

    for (NSString *url in imageURLs) {

      NSMutableURLRequest *request =
          [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
      NSURLSession *session = [NSURLSession sharedSession];

      NSURLSessionTask *task =
          [session dataTaskWithRequest:request
                     completionHandler:^(NSData *_Nullable data,
                                         NSURLResponse *_Nullable response,
                                         NSError *_Nullable error) {

                       NSLog(@"deal with data here url == %@", url);

                       dispatch_semaphore_signal(semaphore);

                     }];

      [task resume];
    }
    NSLog(@"image 2 %@", [NSThread currentThread]);

    for (int i = 0; i < imageURLs.count; i++) {
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    }

    NSLog(@"image 3 %@", [NSThread currentThread]);

  });
}

 

2016-11-12 18:29:10.234 MutipleThreadPractice[4897:4101983] image 2 <NSThread: 0x7fa6e1f2c4b0>{number = 2, name = (null)}
2016-11-12 18:29:10.337 MutipleThreadPractice[4897:4101987] deal with data here url == http://zbimg.25pp.com/images/artwork/246/950137846_54x54.jpg
2016-11-12 18:29:10.358 MutipleThreadPractice[4897:4101987] deal with data here url == http://zbimg.25pp.com/images/artwork/102/951610982_54x54.jpg
2016-11-12 18:29:10.358 MutipleThreadPractice[4897:4101987] deal with data here url == http://zbimg.25pp.com/images/artwork/92/855031900_54x54.jpg
2016-11-12 18:29:10.358 MutipleThreadPractice[4897:4101983] image 3 <NSThread: 0x7fa6e1f2c4b0>{number = 2, name = (null)}

 

 

參考資料

 

http://www.jianshu.com/p/943dcb9ad632

 

https://developer.apple.com/reference/dispatch?language=objc

 

iOS-圖文表並茂,手把手教你GCD

http://www.cocoachina.com/ios/20161031/17887.html

 

淺談GCD中的信號量

http://www.jianshu.com/p/04ca5470f212

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息