完整代码如下:
#import "ViewController.h"@interface ViewController ()@property (nonatomic,weak) NSTimer *timer;@property (nonatomic,strong) dispatch_queue_t queue;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; _queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL); NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(addObjectforArray) userInfo:nil repeats:YES]; [timer fire];}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { dispatch_async(_queue, ^{ NSLog(@"touchesBeganThread:%@",[NSThread currentThread]); });}- (void)addObjectforArray{ dispatch_async(_queue, ^{ NSLog(@"addObjectThread:%@",[NSThread currentThread]); });}
问题如下:
使用串行队列,又使用了 dispatch_async,在touchesBegan 和addObjectforArray里面打印出来的队列应该是同一个线程,但是实际情况却是
2017-08-09 10:33:25.984 nsmutableArrayTest[2734:232067] addObjectThread:<NSThread: 0x6000002626c0>{number = 6, name = (null)}2017-08-09 10:33:25.994 nsmutableArrayTest[2734:232067] addObjectThread:<NSThread: 0x6000002626c0>{number = 6, name = (null)}2017-08-09 10:33:25.998 nsmutableArrayTest[2734:232067] touchesBeganThread:<NSThread: 0x6000002626c0>{number = 6, name = (null)}2017-08-09 10:33:26.004 nsmutableArrayTest[2734:232053] addObjectThread:<NSThread: 0x600000262480>{number = 5, name = (null)}2017-08-09 10:33:26.014 nsmutableArrayTest[2734:232053] addObjectThread:<NSThread: 0x600000262480>{number = 5, name = (null)}
你如何看待这个问题,为什么number 会变化,不应该是开了多个线程,还是怎么回事?
解决方案
可以看下我的这篇博客,或者直接看下面的评论。
队列决定了是并行还是串行,同步异步决定了是否开启新的线程:
并发队列 | 串行队列(非主队列) | 主队列(只有主线程,串行队列) | |
---|---|---|---|
同步 | 不开启新的线程,串行 | 不开启新的线程,串行 | 不开启新的线程,串行 |
异步 | 开启新的线程,并发 | 开启新的线程,串行 | 不开启新的线程,串行 |
所以,即便你是串行队列,但是是异步执行,所以会启用新的线程。