1.NSMutableArray和NSArray实例执行mutableCopy和copy方法的区别?
NSMutableArray *arrM = [NSMutableArray arrayWithArray:@[@1,@2]];
id cp1 = [arrM mutableCopy];
id cp2 = [arrM copy];
NSLog(@"arrM %p, class %@", arrM, NSStringFromClass([arrM class]));
NSLog(@"cp1 %p, class %@", cp1, NSStringFromClass([cp1 class]));
NSLog(@"cp2 %p, class %@", cp2, NSStringFromClass([cp2 class]));
NSArray *arrI = @[@1,@2];
id cp3 = [arrI mutableCopy];
id cp4 = [arrI copy];
NSLog(@"arrI %p, class %@", arrI, NSStringFromClass([arrI class]));
NSLog(@"cp3 %p, class %@", cp3, NSStringFromClass([cp3 class]));
NSLog(@"cp4 %p, class %@", cp4, NSStringFromClass([cp4 class]));
执行结果:
arrM 0x600002e562e0, class __NSArrayM
cp1 0x600002e56610, class __NSArrayM
cp2 0x60000206af40, class __NSArrayI
arrI 0x60000206c380, class __NSArrayI
cp3 0x600002e6d920, class __NSArrayM
cp4 0x60000206c380, class __NSArrayI
上面的问题分两种情况:
- 当可变对象mutablecopy和copy之后,都会生成新的对象,只是新的对象的类型一个是可变的一个是不可变的。
- 当不可变对象mutablecopy和copy之后,只有mutablecopy会生成新的对象,copy则会只复制指针。
2.下面函数的执行结果及发生错误的原因
dispatch_semaphore_t signal;
signal = dispatch_semaphore_create(1);
__block long x = 0;
NSLog(@"0_x:%ld",x);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
NSLog(@"waiting");
x = dispatch_semaphore_signal(signal);
NSLog(@"1_x:%ld",x);
sleep(2);
NSLog(@"waking");
x = dispatch_semaphore_signal(signal);
NSLog(@"2_x:%ld",x);
});
// dispatch_time_t duration = dispatch_time(DISPATCH_TIME_NOW, 1*1000*1000*1000); //超时1秒
// dispatch_semaphore_wait(signal, duration);
x = dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
NSLog(@"wait 1");
NSLog(@"3_x:%ld",x);
x = dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
NSLog(@"wait 2");
NSLog(@"4_x:%ld",x);
x = dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
NSLog(@"wait 3");
NSLog(@"5_x:%ld",x);
结果:
0_x:0
wait 1
3_x:0
waiting
1_x:1
wait 2
4_x:0
waking
2_x:1
wait 3
5_x:0
最后会出现一个Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
的错误
首先看一下信号量的几个函数:
dispatch_semaphore_create(M)
创建一个值为M的信号量
dispatch_semaphore_wait(信号量,等待时间)
如果该信号量的值大于0,则使其信号量的值-1,否则,阻塞线程直到该信号量的值大于0或者达到等待时间。
dispatch_semaphore_signal(信号量)
释放信号量,使得该信号量的值加1
所以上面的结果不难推断出,但是为什么会有最后的错误呢?
在苹果的开发文档上有这么一段话
Calls to
dispatch_semaphore_signal
must be balanced with calls towait()
. Attempting to dispose of a semaphore with a count lower thanvalue
causes anEXC_BAD_INSTRUCTION
exception.
对dispatch_semaphore_signal
的调用必须与wait()
的调用相匹配。试图销毁一个value低于初始化value值的信号将会导致一个EXC_BAD_INSTRUCTION
错误。