Objective-C线程

Mat*_*uyn 3 objective-c

我是如何得到这个结果的世界:

2012-02-15 14:00:46.008 Test[3602:f803] 1: 0
2012-02-15 14:00:46.010 Test[3602:f803] 3: 1
2012-02-15 14:00:46.011 Test[3602:f803] 4: 3
2012-02-15 14:00:46.010 Test[3602:11703] 2: 2
Run Code Online (Sandbox Code Playgroud)

从这段代码:

TestClass * test = [[TestClass alloc] init];
NSLog(@"1: %i", test.value++);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
     NSLog(@"2: %i", test.value++);
});
@synchronized(test) {
     NSLog(@"3: %i", test.value++);
}
NSLog(@"4: %i", test.value++);
Run Code Online (Sandbox Code Playgroud)

我的期望是:

2012-02-15 14:00:46.008 Test[3602:f803] 1: 0
2012-02-15 14:00:46.010 Test[3602:f803] 3: 1
2012-02-15 14:00:46.011 Test[3602:f803] 4: 2
2012-02-15 14:00:46.010 Test[3602:11703] 2: 3
Run Code Online (Sandbox Code Playgroud)

甚至

2012-02-15 14:00:46.008 Test[3602:f803] 1: 0
2012-02-15 14:00:46.010 Test[3602:f803] 3: 1
2012-02-15 14:00:46.010 Test[3602:11703] 2: 2
2012-02-15 14:00:46.011 Test[3602:f803] 4: 3
Run Code Online (Sandbox Code Playgroud)

因为test.value在步骤2的日志中递增,但是没有记录?问心无愧?

das*_*ght 6

NSLog启动调用NSLog到将日志写入日志的时刻之间有一段时间.它可能会在此期间被抢占,因此在此NSLog唤醒实例之前,另一个线程可能潜入其日志条目.

以下是可能导致打印输出的事件序列:

  1. 线程A调用NSLog(@"2: %i", test.value++);,2作为%i参数进入堆栈,并写入3test.value
  2. 线程A在准备日志输出的过程中被抢占
  3. 主线程调用NSLog(@"4: %i", test.value++);,3作为%i参数进入堆栈,并写入4test.value
  4. 主线程写入4: 3日志而不会被抢占
  5. 线程A唤醒,从堆栈中取出2,格式化其输出,并写入2: 2日志