iOS中常NSTimer、CADisplayLink、GCD定时器,其中NSTimer、CADisplayLink基于NSRunLoop实现,故存在偏差,GCD定时器只依赖系统内核,相对一前二者是比较准时的。html
偏差缘由是:与NSRunLoop机制有关, 由于RunLoop每跑完一次圈再去检查当前累计时间是否已经达到定时设置的间隔时间,若是未达到,RunLoop将进入下一轮任务,待任务结束以后再去检查当前累计时间,而此时的累计时间可能已经超过了定时器的间隔时间,故会存在偏差。ios
参考《iOS常见三种定时器-NSTimer、CADisplayLink、GCD定时器》面试
若是直接使用,会产生循环引用问题。能够增长一个中间类,给这个类添加一个用weak修饰的id 类型target属性,并重写中间类的消息转发方法。实现以下代码:算法
声明文件.h:json
#import <Foundation/Foundation.h> @interface LXProxy : NSProxy + (instancetype)proxyWithTarget:(id)target; @end
实现文件.m缓存
#import "LXProxy.h" @interface LXProxy () /** weak target*/ @property (nonatomic, weak) id target; @end @implementation LXProxy + (instancetype)proxyWithTarget:(id)target{ LXProxy *proxy = [LXProxy alloc]; proxy.target = target; return proxy; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{ return [self.target methodSignatureForSelector:sel]; } - (void)forwardInvocation:(NSInvocation *)invocation{ [invocation invokeWithTarget:self.target]; } @end
调用代码:安全
_timer = [NSTimer scheduledTimerWithTimeInterval:2 target:[LXProxy proxyWithTarget:self] selector:@selector(test) userInfo:nil repeats:YES];
runtime是OC动态语言的运行时机制,OC的方法调用最后都转成了runtime的objc_msgSend函数。网络
注:对于已经排序好的方法列表,采用二分查算法查找对应的执行函数,对应没有排序的列表,采用通常遍历方法查找对应执行函数。函数
由此可知, 实例方法(-方法)查找是沿着其superclass指针逐级父类查找,终于根类对象(root class)。而类方法(+方法)查找是沿着其superclass指针逐级父类(meta)查找,终于根类对象(root class),若是根类对象存在同名实例方法,则会调用同名实例方法oop
+initialize 方法,会在第一次初始化这个类以前被调用,咱们用它来初始化静态变量。+load 方法会在加载类的时候就被调用,也就是 ios 应用启动的时候,就会加载全部的类,就会调用每一个类的 +load 方法。initialize 方法相似一个懒加载,若是没有使用这个类,那么系统默认不会去调用这个方法,且默认只加载一次,且调用发生在 +init 方法以前。
调用最后参与编译的分类的test方法。缘由:Xcode在编译时根据buildPhases->Compile Sources里面的从上至下顺序编译的,经过压栈的方式将多个分类压栈,且根据后进先出的原则,后编译的会被先调用(插入顶部添加,即[methodLists insertObject:category_method atIndex:0]。因此objc_msgSend遍历方法列表查找SEL 对应的IMP时,会先找到最后参与编译的分类)当objc_msgSend找到方法并调用以后,结束传递消息,因此就造成了所谓的“覆盖”。
App冷启动优化方案博客很是之多,归纳总结大体以下:
HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全
HTTPS协议的主要做用能够分为两种:一种是创建一个信息安全通道,来保证数据传输的安全;另外一种就是确认网站的真实性。