1、@property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的?
@property是由ivar、getter、setter组成的。
属性被加载到类中的时候,会生成成员变量ivar(由下划线和属性名组成)。
getter和setter是由编译器自动生成并加入到类中。
2、列表卡顿的原因可能有哪些?怎么优化的?
原因:①在主线程中进行了耗时或者同步操作。
②cell过于复杂,子视图层级过多。
③cell种类繁多,样式多种多样。
④没有使用cell的复用机制。
⑤使用了圆角、阴影、半透明等特性,耗费性能。
优化:①同步或耗时操作放在子线程中执行。
②对复杂的cell进行拆分,避免层级过多。
③缓存动态cell的高度,避免重复计算。
④使用复用机制。
⑤使用drawrect绘制,或者让设计师将效果直接做成图片。
3、苹果用什么方式实现对一个对象的KVO?
使用了Runtime机制来实现。当监听一个对象的属性时,Runtime会生成一个新的类,重新setter方法,在属性的值改变的时候,发起通知告诉监听者。然后将对象的isa指向新类,从而实现了KVO。
4、一个objc对象如何进行内存布局?(考虑有父类的情况)
每个对象的成员变量和父类的成员变量都存储在对象的内存区域中。每个对象的isa指针指向了自己的类对象。类对象中存放了isa指针、成员变量列表、方法列表、缓存列表等。类对象的isa指向了元类对象,其中存放了类的isa、方法类型等等。
5、如何用GCD同步若干个异步调用?
使用dispatch_group方法。生成一个group,然后将每个异步调用都添加到该group中。然后再dispatch_group_notify中执行所有异步调用完成后的操作。
6、苹果是如何实现autoreleasepool的?
通过三个方法来实现:autoreleasepoolpush、autoreleasepoolpop、autorelease。
每当一个对象调用了autorelease,那么就会被加入到最近的一个autoreleasepool中,当一个完整的事件循环结束后,就会清空autoreleasepool。
7、以+ scheduledTimerWithTimeInterval...的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?
scheduledTimerWithTimeInterval是将定时器加入到了Runloop的默认模式下,当页面滑动时,Runloop切换到了scrolltrack模式下。此时,默认模式下的timer就会被暂停。
使用[NSTimer timerWith...]方式生成timer对象,然后加入到Runloop的scrolltrack模式下即可。
如果需要在默认模式和滑动模式下都生效,那么将timer加入到commonModes模式下即可。
8、分析下runtime动态方法解析?
当一个对象调用了方法后,那么通过该对象的isa找到其类对象(实例对象是类对象,类对象是元类对象)。然后依次从缓存列表、方法列表中查找对应的selector,如果找到那么加入缓存列表然后去执行该方法。如果未找到,那么去其父类中找,直到NSObject,如果找到操作同上。如果未找到那么进入Runtime的动态方法解析,resolveInstanceMethod或resolveClassMethod。
在动态方法解析中,可以使用class_addMethod方法给对象动态添加一个selector的实现。如果没有做任何处理,那么进入消息重定向和消息转发。
9、怎么理解消息转发流程?
动态方法解析中如果未作处理,那么会进入消息的重定向中,forwardingTargetForSelector。在此方法中,可以将消息转发给一个已有的可以现有该selector的对象。如果没有,那么返回nil,进入消息转发流程。
消息转发,执行的是forwardInvocation方法。首先调用methodSignatureForSelector方法获取方法签名,如果获取不到那么调用系统方法doesNotRecognizeSelector方法抛出异常。如果获取到了方法签名,那么Runtime会生成一个invocation对象,然后使用参数invoke取出selector,结合方法签名,配置好invocation对象返回即可。消息转发流程结束。
10、剖析iOS动态链接库加载过程?
Runtime会调用每个类的load方法(只会调用一次),加载顺序是父类、子类、分类。然后执行main函数。之后使用到哪个类就去调用哪个类的initialization方法,加载顺序是父类、子类、分类。
load方法中一般进行全局变量、静态变量等的初始化,或者method swizzling。initialization中一般进行该类使用到的变量等的初始化工作。能在initialization中进行的操作就尽量不要在load中进行。
网友评论