美文网首页
iOS面试题(四)

iOS面试题(四)

作者: WinJayQ | 来源:发表于2018-05-30 00:03 被阅读20次

    1、申请后台运行除了后台刷新和VoIP及音乐播放和定位之外还有什么办法?

    UIBackgroundTaskIdentifier

    2、你们项目中为什么多线程用GCD而不用NSOperation呢? 你有没有发现国外的大牛他们多线程都是用NSOperation? 你能告诉我他们这样做的理由吗?

    关系:①:先搞清两者的关系,NSOpertaionQueue用GCD构建封装的,是GCD的高级抽象!
    ②:GCD仅仅支持FIFO队列,而NSOperationQueue中的队列可以被重新设置优先级,从而实现不同操作的执行顺序调整。GCD不支持异步操作之间的依赖关系设置。如果某个操作的依赖另一个操作的数据(生产者-消费者模型是其中之一),使用NSOperationQueue能够按照正确的顺序执行操作。GCD则没有内建的依赖关系支持。
    ③:NSOperationQueue支持KVO,意味着我们可以观察任务的执行状态。
    了解以上不同,我们可以从以下角度来回答
    性能:①:GCD更接近底层,而NSOperationQueue则更高级抽象,所以GCD在追求性能的底层操作来说,是速度最快的。这取决于使用Instruments进行代码性能分析,如有必要的话
    ②:从异步操作之间的事务性,顺序行,依赖关系。GCD需要自己写更多的代码来实现,而NSOperationQueue已经内建了这些支持
    ③:如果异步操作的过程需要更多的被交互和UI呈现出来,NSOperationQueue会是一个更好的选择。底层代码中,任务之间不太互相依赖,而需要更高的并发能力,GCD则更有优势

    3、什么是KVC和KVO?

    KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环 境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。KVO(Key-Value- Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。所以 isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名

    4、如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?

    若想令自己所写的对象具有拷贝功能,则需实现 NSCopying 协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现 NSCopying 与 NSMutableCopying 协议。
    具体步骤:
    1. 需声明该类遵从 NSCopying 协议
    2. 实现 NSCopying 协议的方法。
    // 该协议只有一个方法:
    - (id)copyWithZone:(NSZone *)zone;
    // 注意:使用 copy 修饰符,调用的是copy方法,其实真正需要实现的是 “copyWithZone” 方法。

    5、@synthesize 和 @dynamic 分别有什么作用?

    @property有两个对应的词,一个是@synthesize(合成实例变量),一个是@dynamic。
    如果@synthesize和@dynamic都没有写,那么默认的就是 @synthesize var = _var;
    // 在类的实现代码里通过 @synthesize 语法可以来指定实例变量的名字。(@synthesize var = _newVar;)

    1. @synthesize 的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。
    2. @dynamic 告诉编译器,属性的setter与getter方法由用户自己实现,不自动生成(如,@dynamic var)。

    6、如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)

    // 使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。
    // 创建队列组
    dispatch_group_t group = dispatch_group_create();
    // 获取全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(group, queue, ^{ /*加载图片1 */ });
    dispatch_group_async(group, queue, ^{ /*加载图片2 */ });
    dispatch_group_async(group, queue, ^{ /*加载图片3 */ }); 
    // 当并发队列组中的任务执行完毕后才会执行这里的代码
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // 合并图片
    });
    

    7、dispatch_barrier_async(栅栏函数)的作用是什么?

    函数定义:dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
    作用:
        1.在它前面的任务执行结束后它才执行,它后面的任务要等它执行完成后才会开始执行。
        2.避免数据竞争
    
    // 1.创建并发队列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    // 2.向队列中添加任务
    dispatch_async(queue, ^{  // 1.2是并行的
        NSLog(@"任务1, %@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任务2, %@",[NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"任务 barrier, %@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{   // 这两个是同时执行的
        NSLog(@"任务3, %@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任务4, %@",[NSThread currentThread]);
    });
    
    // 输出结果: 任务1 任务2 ——》 任务 barrier ——》任务3 任务4 
    // 其中的任务1与任务2,任务3与任务4 由于是并行处理先后顺序不定。
    

    8、什么是 RunLoop

    从字面上讲就是运行循环,它内部就是do-while循环,在这个循环内部不断地处理各种任务。
    一个线程对应一个RunLoop,基本作用就是保持程序的持续运行,处理app中的各种事件。通过runloop,有事运行,没事就休息,可以节省cpu资源,提高程序性能。

    主线程的run loop默认是启动的。iOS的应用程序里面,程序启动后会有一个如下的main()函数
    int main(int argc, char * argv[]) {
    @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
    }

    9、Runtime实现的机制是什么,怎么用,一般用于干嘛?

    1). 使用时需要导入的头文件 <objc/message.h> <objc/runtime.h>
    2). Runtime 运行时机制,它是一套C语言库。
    3). 实际上我们编写的所有OC代码,最终都是转成了runtime库的东西。
    比如:
    类转成了 Runtime 库里面的结构体等数据类型,
    方法转成了 Runtime 库里面的C语言函数,
    平时调方法都是转成了 objc_msgSend 函数(所以说OC有个消息发送机制)
    // OC是动态语言,每个方法在运行时会被动态转为消息发送,即:objc_msgSend(receiver, selector)。
    // [stu show]; 在objc动态编译时,会被转意为:objc_msgSend(stu, @selector(show));
    4). 因此,可以说 Runtime 是OC的底层实现,是OC的幕后执行者。
    有了Runtime库,能做什么事情呢?
    Runtime库里面包含了跟类、成员变量、方法相关的API。
    比如:
    (1)获取类里面的所有成员变量。
    (2)为类动态添加成员变量。
    (3)动态改变类的方法实现。
    (4)为类动态添加新的方法等。
    因此,有了Runtime,想怎么改就怎么改。

    10、什么是 TCP / UDP ?

    TCP:传输控制协议。
    UDP:用户数据协议。

    TCP 是面向连接的,建立连接需要经历三次握手,是可靠的传输层协议。
    UDP 是面向无连接的,数据传输是不可靠的,它只管发,不管收不收得到。
    简单的说,TCP注重数据安全,而UDP数据传输快点,但安全性一般。

    答案都是收集而来,如果有什么错误,欢迎指正!

    相关文章

      网友评论

          本文标题:iOS面试题(四)

          本文链接:https://www.haomeiwen.com/subject/gouzjftx.html