情形1:
dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"不会执行"); });
如果在主线程添加这段代码,即同步执行添加到主队列的block。这个函数会等block执行完毕返回主线程,再继续执行下面的代码,而block要等主线程返回才会执行,所以循环等待造成死锁。
如果改成异步就可以了,因为当前主线程的一次runloop会马上返回,下一次runloop则会执行主队列里的block。
dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"会执行"); });
还有一个用于在主线程更新ui的方法,如果在主线程执行它,即使是同步的,也并不会造成死锁。
[self performSelectorOnMainThread:@selector(logTest) withObject:nil waitUntilDone:YES];
情形2:
关于operationqueue的。
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"111"); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"222"); }]; NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"333"); }]; NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"444"); }]; NSArray *arr = [NSArray arrayWithObjects: op1, op2, op3, op4, nil]; [[NSOperationQueue mainQueue]addOperations:arr waitUntilFinished:NO];
NSLog(@"2");
也是在主线程当中异步执行,所以以上代码会正常运行,并且运行按照顺序,因为主队列是串行队列。
结果:
2015-07-01 14:07:34.064 TestProject[1388:318202] 1 2015-07-01 14:07:34.065 TestProject[1388:318202] 2 2015-07-01 14:07:34.070 TestProject[1388:318202] 111 2015-07-01 14:07:34.071 TestProject[1388:318202] 222 2015-07-01 14:07:34.073 TestProject[1388:318202] 333 2015-07-01 14:07:34.073 TestProject[1388:318202] 444
如果改为同步执行,则会造成死锁:
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"111"); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"222"); }]; NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"333"); }]; NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"444"); }]; NSArray *arr = [NSArray arrayWithObjects: op1, op2, op3, op4, nil]; [[NSOperationQueue mainQueue]addOperations:arr waitUntilFinished:YES]; NSLog(@"2");
结果:
2015-07-01 14:10:48.577 TestProject[1423:335286] 1
主队列等待当前的运行循环结束,然后运行队列中的block,而当前运行循环在等待
addOperations 的返回,所以当前运行循环永远不会结束,所以主队列中的block永远不会执行到,程序就这样卡住了。
如果另外创建一个队列(不会是主队列),用同步执行的话:
<pre name="code" class="objc">NSLog(@"1"); NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"111"); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"222"); }]; NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"333"); }]; NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"444"); }]; NSArray *arr = [NSArray arrayWithObjects: op1, op2, op3, op4, nil]; NSOperationQueue *queue = [[NSOperationQueue alloc]init];//并发,顺序不定 [queue addOperations:arr waitUntilFinished:YES]; NSLog(@"2");
运行结果如下:
<pre name="code" class="objc">2015-07-01 14:14:44.417 TestProject[1480:353564] 1 2015-07-01 14:14:44.418 TestProject[1480:353689] 111 2015-07-01 14:14:44.418 TestProject[1480:353705] 444 2015-07-01 14:14:44.418 TestProject[1480:353690] 333 2015-07-01 14:14:44.419 TestProject[1480:353685] 222 2015-07-01 14:14:44.419 TestProject[1480:353564] 2
结果正常。因为新创建的队列是可以并发的,所以1,2,3,4的执行顺序不一定。
如果改为异步执行,同样正常执行,1,2,3,4block执行顺序不定,但函数会立即返回。
<pre name="code" class="objc">NSLog(@"1"); NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"111"); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"222"); }]; NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"333"); }]; NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"444"); }]; NSArray *arr = [NSArray arrayWithObjects: op1, op2, op3, op4, nil]; NSOperationQueue *queue = [[NSOperationQueue alloc]init];//并发,顺序不定 [queue addOperations:arr waitUntilFinished:NO]; NSLog(@"2");
运行结果:
<pre name="code" class="objc">2015-07-01 14:17:53.111 TestProject[1513:365712] 1 2015-07-01 14:17:53.112 TestProject[1513:365712] 2 2015-07-01 14:17:53.112 TestProject[1513:365832] 333 2015-07-01 14:17:53.112 TestProject[1513:365831] 111 2015-07-01 14:17:53.112 TestProject[1513:365837] 444 2015-07-01 14:17:53.113 TestProject[1513:365830] 222
即使主线程阻塞了,1,2,3,4也会正常执行。
情形3:
<pre name="code" class="objc">NSLog(@"1"); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"=================1"); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"=================2"); }); NSLog(@"=================3"); }); NSLog(@"2"); while (1) { }
同步执行主队列的block不会执行,因为当前运行循环不会结束。由于是同步的,所以下面的====3也不会执行到。
运行结果:
<pre name="code" class="objc">2015-07-01 14:21:25.499 TestProject[1651:389143] 1 2015-07-01 14:21:25.499 TestProject[1651:389143] 2 2015-07-01 14:21:25.499 TestProject[1651:389172] =================1
如果改为异步在主线程执行,则====3会执行。
<pre name="code" class="objc">NSLog(@"1"); dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"=================1"); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"=================2"); }); NSLog(@"=================3"); }); NSLog(@"2"); while (1) { }
结果:
<pre name="code" class="objc">2015-07-01 14:24:54.855 TestProject[1687:402116] 1 2015-07-01 14:24:54.855 TestProject[1687:402116] 2 2015-07-01 14:24:54.855 TestProject[1687:402152] =================1 2015-07-01 14:24:54.855 TestProject[1687:402152] =================3
总结:
在主线程中不要同步执行在主队列中的block。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-11 06:25:32