dispatch_sync(concurrent_queue, ^{ NSLog(@"打印%d----线程:%@", i,[NSThread currentThread]); //在当前线程中执行...self.view.backgroundColor = [UIColor orangeColor]; dispatch_sync(dispatch_get_main_queue(), ^{...原因是ViewDidLoad是在主队列的主线程中执行,执行到dispatch_sync 时会阻塞住,等待dispatch_sync中的打印任务执行完毕。...而dispatch_sync又会等viewDidLoad执行完毕,再开始执行,因此就互相等待发生死锁。 ** 情形二 ** 在串行队列的同步任务中再执行同步任务,会发生死锁。...(serial_queue, ^{ NSLog(@"串行1----线程:%@",[NSThread currentThread]); dispatch_sync(serial_queue
dispatch_barrier_async() 将任务添加到队列中,此任务执行的时候,其他任务停止执行 dispatch_once() 任务添加到队列中,但任务在程序运行过程中,只执行一次 dispatch_sync...@"执行1:%@", [NSThread currentThread]); sleep(2); NSLog(@"完成1:%@", [NSThread currentThread]); }); dispatch_sync...@"执行2:%@", [NSThread currentThread]); sleep(3); NSLog(@"完成2:%@", [NSThread currentThread]); }); dispatch_sync...,阻塞 6、同步-并发 dispatch_queue_t queue = dispatch_queue_create("moxiaoyan", DISPATCH_QUEUE_CONCURRENT); dispatch_sync...@"执行1:%@", [NSThread currentThread]); sleep(2); NSLog(@"完成1:%@", [NSThread currentThread]); }); dispatch_sync
1.2 GCD函数 同步函数 通过dispatch_sync(queue , {})获取; 必须等待当前语句执行完毕,才会执行下一条语句; 不会开启其他线程,就在当前线程中完成任务; 异步函数...2、GCD的使用 2.1 创建 同步函数 dispatch_sync(dispatch_get_main_queue();, ^{ }); 异步函数 dispatch_async(dispatch_get_main_queue...; 2.2 串行队列同步函数 -(void)demo{ dispatch_queue_t queue = dispatch_queue_create("HRTest", NULL); dispatch_sync...(queue, ^{ dispatch_sync(queue, ^{ NSLog(@"1"); }); NSLog(@"2");...(queue, ^{ NSLog(@"%@",[NSThread currentThread]); NSLog(@"2"); dispatch_sync(
dispatch_async(con_queue, ^{ NSLog(@"1----%@",NSThread.currentThread); }); dispatch_sync...(con_queue, ^{ NSLog(@"2----%@",NSThread.currentThread); }); dispatch_sync...dispatch_async(queue, ^{ NSLog(@"1---%@",NSThread.currentThread); dispatch_sync...NSLog(@"3---%@",NSThread.currentThread); }); dispatch_sync...dispatch_async(queue, ^{ NSLog(@"1---%@",NSThread.currentThread); dispatch_sync
com.effective-c.syncQueue", NULL); -(NSString*) someString { __block NSString* localSomething; dispatch_sync...someString; }); return localSomeString } -(void) setSomeString:(NSString*) someString{ dispatch_sync...DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); -(NSString *)someString { __block NSString *localSomeString; dispatch_sync
任务的取出遵循队列的FIFO原则:First in first out GCD路径iOS usr/include/dispatch/下查看头文件说明 GCD常用方法 执行任务 dispatch_sync...NSLog(@"下载图片2---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"下载图片3-...NSLog(@"下载图片2---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"下载图片3-...但dispatch_sync()方法必须返回才能往下执行,其返回的条件是Block的内容执行完毕才行。...也就是说死锁的条件是因为dispatch_sync()方法在等待Block执行完毕,而Block在等待dispatch_sync()方法往下执行才能轮到它。
时 为串行 当队列为串行时 队列中的block按照先进先出(FIFO)的顺序去执行,实际上为单线程执行 当队列为并行时,没有固定的顺序,为多线程执行 队列执行 基本 dispatch_async 和 dispatch_sync...dispatch_sync(queue, ^{ //block具体代码 }); 实际编程经验告诉我们,尽可能避免使用dispatch_sync,嵌套使用时还容易引起程序死锁。...死锁例子 死锁例子1 如果queue1是一个串行队列的话,这段代码立即产生死锁: dispatch_sync(queue1, ^{ dispatch_sync(queue1, ^{ //......... }); //...... }); 死锁例子2 主线程中执行会死锁 dispatch_sync(dispatch_get_main_queue(), ^{ //.........然后可以用dispatch_async 或者 dispatch_sync将共享数据的访问代码封装起来: - (id)something { __block id localSomething;
(void)serialSyn{ dispatch_queue_t queue =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL); dispatch_sync...for (int i =0; i <3; i ++) { NSLog(@"1---%@", [NSThreadcurrentThread]); } }); dispatch_sync...for (int i =0; i <3; i ++) { NSLog(@"2---%@", [NSThreadcurrentThread]); } }); dispatch_sync...for (int i =0; i <3; i ++) { NSLog(@"1---%@", [NSThreadcurrentThread]); } }); dispatch_sync...NSLog(@"===========1"); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"===========2");
调用dispatch_sync()方法会把任务同步提交到指定的队列。...从原理来看,死锁的原因是提交的 block 阻塞了队列,而队列阻塞后永远无法执行完dispatch_sync(),可见这里完全和代码所在的线程无关。...根据上文选择线程的原则,block 将在主线程中执行,但同样不会导致死锁: dispatch_queue_tqueue=dispatch_queue_create("com.kt.deadlock",nil); dispatch_sync...theLabel; if([NSThreadisMainThread]){ theLabel=[[UILabelalloc]init]; [theLabelsetText:text]; } else{ dispatch_sync...Community bug reports about MapKit GCD’s Main Queue vs Main Thread ReactiveCocoa 中遇到类似的坑 Why can’t we use a dispatch_sync
Demo1 NSLog(@"1"); // 任务1 dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"2"); // 任务2 });...DispatchQueue.main.sync { print("2") //任务2 } print("3") //任务3 接下来 控制器输出: 1 分析: dispatch_sync...Demo2 NSLog(@"1"); // 任务1 dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),...DISPATCH_QUEUE_SERIAL); NSLog(@"1"); // 任务1 dispatch_async(queue, ^{ NSLog(@"2"); // 任务2 dispatch_sync...Demo5 dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"1"); // 任务1 dispatch_sync(
我们GCD使用常伴有dispatch_sync和dispatch_async,这就是同步执行和异步执行。 同步和异步 同步执行:任务都在当前线程中执行,执行过程中会阻塞当前线程。...viewDidLoad里 dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL); dispatch_sync...^{ NSLog(@"task1"); NSLog(@"task1---%@",[NSThread currentThread]); }); dispatch_sync...^{ NSLog(@"task2"); NSLog(@"task2---%@",[NSThread currentThread]); }); dispatch_sync...^{ NSLog(@"task1"); NSLog(@"task1---%@",[NSThread currentThread]); }); dispatch_sync
在这些情况下,您可以使用dispatch_sync和dispatch_sync_f函数将任务添加到队列中。这些函数会阻塞当前的执行线程,直到指定的任务完成执行。...重要提示: 您永远不应从在您计划传递给函数的同一队列中执行的任务调用dispatch_sync或dispatch_sync_f函数。这对于保证死锁的串行队列尤其重要,但对于并发队列也应避免。...在GCD函数和队列篇章中,我们知道dispatch_syn函数的执行流程如下: dispatch_sync -> _dispatch_sync_f -> _dispatch_sync_f_inline...= _DISPATCH_LANE_TYPE)) { DISPATCH_CLIENT_CRASH(0, "Queue type doesn't support dispatch_sync");...= _DISPATCH_LANE_TYPE)) { DISPATCH_CLIENT_CRASH(0, "Queue type doesn't support dispatch_sync");
1、添加任务到队列(同步、异步): dispatch_sync: 同步添加,将指定的任务block同步追加到queue中,在追加的block结束之前,dispatch_sync会一直等待; 如果在主线程上执行同步任务...(任务也在主线程执行),会造成死锁: //会造成死锁 dispatch_sync(dispatch_get_main_queue(), ^{ // }); 但是在异步任务里可以用来切换到主线程 dispatch_async...(dispatch_get_global_queue(0,0), ^{ //耗时操作; dispatch_sync(dispatch_get_main_queue(), ^{ //回到主线程;...}); }); 可以用来阻塞线程: dispatch_sync(dispatch_get_global_queue(0,0), ^{ sleep(2); NSLog(@"2秒后执行,但是会阻塞线程
sleep"] = ^(int time) { sleep(time); }; context2[@"log"] = ^(NSString *str){ NSLog(@"%@", str); dispatch_sync...self.context1 = [[JSContext alloc] init]; self.context1[@"log"] = ^(NSString *str) { NSLog(@"%@", str); dispatch_sync...既然发生死锁了,那么我们就一步步庖丁解牛吧,从堆栈看,线程111由于有dispatch_sync,所以要等待主线程,这个比较好理解,可是主线程的堆栈全是JSCore相关代码,根本无从下手,但是从名字上看似乎与...TimerDidFire才被触发,这样主线程也不会被锁 但假如是工作线程先执行JS代码,VM的锁被工作线程持有了,然后主线程触发TimerDidFire,那么主线程就要等待工作线程释放VM的锁,然而这时工作线程又要dispatch_sync
同步:你必须把我的代码执行完你再走,一定要执行完同步里的代码再执行下面的代码 void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block...主队列: 遇到主队列,不管同步异步都要先执行完主线程里的代码再执行主队列里的代码 dispatch_sync方法不能在主队列中调用,因为这会无限期的阻止线程并会导致你的应用死锁。...@"begin"); for (int i = 0; i < 10; i++) { //死锁,一看同步就不分子线程了,一看主队列,就等着主线程执行完来执行里面代码 dispatch_sync...dispatch_async(dispatch_get_global_queue(0, 0), ^{ for (int i = 0; i < 10; i++) { dispatch_sync...同步:你必须把我的代码执行完你再走,一定要执行完同步里的代码再执行下面的代码 void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block
void *_Nullable context, dispatch_function_t work); /* 以同步方式执行任务,阻塞当前线程,必须等待任务完成当前线程才可继续执行 */ void dispatch_sync...而这里是使用同步提交到串行队列去执行任务,当第一个dispatch_sync方法执行后会阻塞当前线程,必须得等第一个任务完成后才能继续,所以这里的执行顺序是提交第一个任务后就开始执行而且得等到第一个任务完成后再去执行第二个...dispatch_sync方法用于提交第二个任务,以此类推。...currentThread], i); } }); } 执行程序后可以发现,不论输出多少次都是按Task1-3顺序输出,相信大家应该明白是为什么了,因为同步提交阻塞当前线程,第一个dispatch_sync...提交的任务完成以后当前线程才能去执行第二个dispatch_sync方法然后执行第二个任务。
GCD总结:将任务(要在线程中执行的操作block)添加到队列(自己创建或使用全局并发队列),并且指定执行任务的方式(异步dispatch_async,同步dispatch_sync) No.3:队列的创建方法...代码如下: // 同步执行任务 dispatch_sync(dispatch_get_global_queue(0, 0), ^{ // 任务放在这个block里...dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL); // 同步执行 dispatch_sync...= 0; i < 3; i++) { NSLog(@"串行同步1 %@",[NSThread currentThread]); } }); dispatch_sync...dispatch_apply函数说明 * * @brief dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API
在这种情况下,dispatch_sync 就是一个绝好的候选。 dispatch_sync() 同步地提交工作并在返回前等待它完成。...如果你使用第二种情况做事,你将不时看到一个 __block 变量写在 dispatch_sync 范围之外,以便返回时在 dispatch_sync 使用处理过的对象。 但你需要很小心。...dispatch_sync 回顾 - (void)viewDidLoad { [super viewDidLoad]; dispatch_sync(dispatch_get_global_queue...主线程目前在 viewDidLoad 内,正要到达 dispatch_sync 。 dispatch_sync Block 被添加到一个全局队列中,将在稍后执行。...全局队列处理 dispatch_sync Block 加入之前已经出现在队列中的任务。 终于,轮到 dispatch_sync Block 。 这个 Block 完成,因此主线程上的任务可以恢复。
dispatch_queue_t queue,void *context,dispatch_function_t work); //将代码块以同步方式提交给指定队列,该队列底层的线程池将负责执行该代码块 dispatch_sync...如下 - (IBAction)clicked:(id)sender { // 以同步方式先后提交2个代码块 dispatch_sync(dispatch_get_global_queue...] , i); [NSThread sleepForTimeInterval:0.1]; } }); // 必须等第一次提交的代码块执行完成后,dispatch_sync...dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) , ^(void){ for
领取专属 10元无门槛券
手把手带您无忧上云