iOS分享世界

两个iOS面试题

2020-04-13  本文已影响0人  摩卡奇

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

上面的问题分两种情况:

  1. 当可变对象mutablecopy和copy之后,都会生成新的对象,只是新的对象的类型一个是可变的一个是不可变的。
  2. 当不可变对象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 to wait(). Attempting to dispose of a semaphore with a count lower than value causes an EXC_BAD_INSTRUCTION exception.

dispatch_semaphore_signal的调用必须与wait()的调用相匹配。试图销毁一个value低于初始化value值的信号将会导致一个EXC_BAD_INSTRUCTION错误。

上一篇 下一篇

猜你喜欢

热点阅读