欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-05-16 09:51:31
1、申请后台运行除了后台刷新和voip及音乐播放和定位之外还有什么办法? uibackgroundtaskidentifier 2、你们项目中为什么多线程用gcd而不用nsoperation呢?...

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). 使用时需要导入的头文件

10、什么是 tcp / udp ?

tcp:传输控制协议。
udp:用户数据协议。

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