iOS面试题(八)

1、xcode在 release 模式下断点调试, 对象在打印的时候有值,断点调试却没值, 这是怎么回事?

设置Build Settings->Optimization Level 为None[-OO],就可以了

image.png

改为:


image.png

2、不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)

分两种情况:手动干预释放时机、系统自动去释放。

    1. 手动干预释放时机—指定autoreleasepool 就是所谓的:当前作用域大括号结束时释放。
    1. 系统自动去释放—不手动指定autoreleasepool

Autorelease对象出了作用域之后,会被添加到最近一次创建的自动释放池中,并会在当前的 runloop 迭代结束时释放。

3、objc在向一个对象发送消息时,发生了什么?

objc在向一个对象发送消息时,runtime库会根据对象的isa指针找到该对象实际所属的类,然后在该类中的方法列表以及其父类方法列表中寻找方法运行,然后在发送消息的时候,objc_msgSend方法不会返回值,所谓的返回内容都是具体调用时执行的。

4、OS objc_msgSend 报错解决方案 以及 内存泄漏的问题?

objc_msgSend(self, @selector(doSomething), self);====>这个函数使用会报错:Too many arguments to function call, expected 0, have 3
错解决方案:选中项目 - Project - Build Settings - ENABLE_STRICT_OBJC_MSGSEND 将其设置为 NO 即可

之前32位的时候没问题,然后转换为64位之后就会发生EXC_BAD_ACCESS问题。

你必须先定义原型才可以使用,这样才不会发生崩溃:
int (action)(id, SEL, int) = (int ()(id, SEL, int)) objc_msgSend;
action(self, @selector(doSomething:), 0);

5、main()之前的过程有哪些?

1)dyld 开始将程序二进制文件初始化
2)交由ImageLoader 读取 image,其中包含了我们的类,方法等各种符号(Class、Protocol 、Selector、 IMP)
3)由于runtime 向dyld 绑定了回调,当image加载到内存后,dyld会通知runtime进行处理
4)runtime 接手后调用map_images做解析和处理
5)接下来load_images 中调用call_load_methods方法,遍历所有加载进来的Class,按继承层次依次调用Class的+load和其他Category的+load方法
6)至此 所有的信息都被加载到内存中
7)最后dyld调用真正的main函数

6、sa指针?(对象的isa,类对象的isa,元类的isa都要说)

对象的isa指针指向所属的类
类的isa指针指向了所属的元类
元类的isa指向了根元类,根元类指向了自己。

7、KVO基本原理?

1 )KVO是基于runtime机制实现的
2 )当某个类的属性对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter 方法。派生类在被重写的setter方法内实现真正的通知机制
3 )如果原类为Person,那么生成的派生类名为NSKVONotifying_Person
4 )每个类对象中都有一个isa指针指向当前类,当一个类对象的第一次被观察,那么系统会偷偷将isa指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的setter方法
5 )键值观察通知依赖于NSObject 的两个方法: willChangeValueForKey: 和 didChangevlueForKey:;在一个被观察属性发生改变之前, willChangeValueForKey:一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey:会被调用,继而 observeValueForKey:ofObject:change:context: 也会被调用。

8、RunLoop是什么?

Run Loop是一让线程能随时处理事件但不退出的机制。RunLoop 实际上是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 “接受消息->等待->处理” 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。让线程在没有处理消息时休眠以避免资源占用、在有消息到来时立刻被唤醒。

OSX/iOS 系统中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef。CFRunLoopRef 是在 CoreFoundation 框架内的,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的。NSRunLoop 是基于 CFRunLoopRef 的封装,提供了面向对象的 API,但是这些 API 不是线程安全的。

线程和 RunLoop 之间是一一对应的,其关系是保存在一个全局的 Dictionary 里。线程刚创建时并没有 RunLoop,如果你不主动获取,那它一直都不会有。RunLoop 的创建是发生在第一次获取时,RunLoop 的销毁是发生在线程结束时。你只能在一个线程的内部获取其 RunLoop(主线程除外)

9、怎样防止反编译?

本地数据加密
对NSUserDefaults,sqlite存储文件数据加密,保护帐号和关键信息
URL编码加密
对程序中出现的URL进行编码加密,防止URL被静态分析
网络传输数据加密
对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取数据
方法体,方法名高级混淆
对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码
程序结构混排加密
对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低

10、多线程安全隐患

多线程安全隐患:

  • 一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源;
  • 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题;

安全隐患解决方法

互斥锁@synchornized(锁对象){需要锁定的代码}
注意:锁定一份代码只用一把锁,用多把锁是无效的;
互斥锁的优缺点:

  • 优点:能有效防止因多线程抢夺资源造成的数据安全问题;
  • 缺点:需要消耗大量的CPU资源;
    互斥锁使用条件:多条线程抢夺同一块资源;
    线程同步:多条线程在同一条线上执行(按顺序地执行任务);
    互斥锁就是达到了线程同步技术;
    在这里补充一下,nonatomic和atomic对比,atomic线程安全,需要消耗大量的资源,nonatomic非线程安全,适合内存小的移动设备;iOS开发建议,所有属性声明为nonatomic,尽量避免多线程请多同一块资源,尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力;

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

你可能感兴趣的:(iOS面试题(八))