情形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。