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

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息