第三方库
AFNetworking
iOS客户端的第三方网络框架,代码地址
架构图
AFURLSessionManager
- 创建和管理NSURLSession、NSURLSessionTask
- 实现NSURLSessionDelegate等协议的代理方法
- 引入AFSecurityPolicy保证请求安全
- 引入AFNetworkReachabilityManager监控网络状态
类的关系
SDWebImageView
架构图
缓存流程
Reactive Cocoa
函数响应式编程框架,源代码地址
函数式编程它的核心思想是,它是一种将程序看成是数学方法的求值、不会改变状态、不会产生副作用(后面我们马上会谈到)的编程方式
响应式编程
RAC库是否了解
- RAC是一个函数式响应编程
- 信号和订阅
信号
-
核心类RACSignal 继承于RACStream
- 使用了抽象工厂、类簇设计模式,返回的对象都是抽象对象,实际上是通过不同的方法创建的具体对象也不同
如何理解信号
核心思想是RACSignal继承RACStream,RACStream的提供了方法:empty、return、bind、concat、zipWith这些都是抽象的函数,RACStream分类中有一些方法:map、take、skip、ignore、filter。。这些函数是对上述提供的抽象函数的不同组合逻辑。
什么是信号
信号代表一连串的状态,在状态改变时,对应的订阅者RACSubscriber就会收到通知,执行响应的指令。
- RACReturnSignal 比如说
[RACSignal return:@3]
这个调用的就是RACReturnSignal的return- 覆盖RACStream中的return方法
- 对传递进来的对象进行包装把它返回给调用方,把OC对象封装成一个信号返回给调用方
- return返回的实例就是信号
订阅
RACSubscriber订阅者,订阅的流程:
把传进来的Block参数,作为这个信号的成员变量保存下来,比如[nal subscribeNext:^(id _Nullable x) {}]
产生了RACSubscriber的类时候,在内部持有一个成员变量,内部的变量是didSubscribe的这个block,当调用RACSignal 的方法的时候,实际上就是执行内部保存的block;
例子分析:
RACSignal *nal = [RACSignal return:@3];
[nal subscribeNext:^(id _Nullable x) {}];
RACSignal *nal = [RACSignal return:@3]
分析
- 首先分析[RACSignal return:@3]的方法,我们打开源码可以看到,是调用了RACReturnSignal的return方法。
+ (RACSignal *)return:(id)value {
return [RACReturnSignal return:value];
}
- 而RACReturnSignal的return方法主要工作是创建一个RACReturnSignal的对象,并将值赋值给这个对象。
RACReturnSignal *signal = [[self alloc] init];
signal->_value = value;
return signal;
[nal subscribeNext:^(id _Nullable x) {}]的分析
1、当RACSignal的实例对象调用了subscribeNext的方法,该方法通过调用
RACSubscriber
的类方法subscriberWithNext
得到RACSubscriber
对象2、
subscriberWithNext
的方法内部是将nextBlock
block保存到RACSubscriber
对象当中3、通过调用
RACSubscriber
的类方法subscriberWithNext
得到RACSubscriber
对象后,调用了RACSubscriber
实例对象的subscribe
方法4、
subscribe
方法是RACReturnSignal
中的subscribe
方法,因为上面的return方法返回的是RACReturnSignal
对象。-
5、
subscribe
中的方法实现- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber { NSCParameterAssert(subscriber != nil); //RACScheduler.subscriptionScheduler是一个单例,而schedule方法只是为了调用这个block return [RACScheduler.subscriptionScheduler schedule:^{ [subscriber sendNext:self.value]; [subscriber sendCompleted]; }]; } @implementation RACSubscriptionScheduler - (RACDisposable *)schedule:(void (^)(void))block { NSCParameterAssert(block != NULL); if (RACScheduler.currentScheduler == nil) return [self.backgroundScheduler schedule:block]; block();//只是做了一个调用block return nil; } @end
6、当
schedule
的block方法调用的时候,调用了RACSubscriber
实例对象的- (void)sendNext:(id)value
方法。-
7、最终在
sendNext
方法中调用了RACSubscriber
实例对象中的nextBlock
的block- (void)sendNext:(id)value { @synchronized (self) { void (^nextBlock)(id) = [self.next copy]; if (nextBlock == nil) return; nextBlock(value); } }
8、上述代码
void (^nextBlock)(id) = [self.next copy];
这个block
恰好就是通过调用RACSubscriber
的类方法subscriberWithNext
得到RACSubscriber
实例对象时,保存到RACSubscriber
实例对象的block9、最终的结果就是
[nal subscribeNext:^(id _Nullable x) {}]
中的x就是RACSignal *nal = [RACSignal return:@3]
中的3
AsyncDisPlayKit
提升iOS界面渲染性的一个框架,代码地址
减轻主线程压力,把事情能放入到子线程的就放入到子线程,主要分为三个方面:
- layout 文本宽高计算、视图布局计算
- Rendering 文本渲染、图片解码、图形绘制
- UIKit Objects 对象创建、对象调整、对象销毁
ASDK实现原理
UIView作为CALyaer的一个delegate,CALyaer作为UIView的一个成员变量负责UIView的展示工作,ASDK在此之上封装了一个NSNode类,而这个类当中会有一个.view或者一个成员变量,可以生成一个view,同时每一个uiview都有一个.node的一个属性可以获取到它所对应的节点。
UIView、CALayer和NSNode、UIView的区别是?
NSNode、UIView中的NSNode是可以放入到后台线程去处理的。是线程安全的。
而UIView和CALayer包括UIKit的内容都是在主线程上做的。
NSNode对UIView进行了一次包装,包括文本宽高计算、视图布局计算、文本渲染、图片解码、徒刑绘制、对象的创建、对象调整、对象销毁,通过操作NSNode来实现,还可以放入到后台执行。
总结:
- 针对ASNode的修改和提交,会对其进行封装并提交到一个全局容器中去。
- 对UIView的修改都落地到NSNode的修改, 模仿系统CAAnimation提交CALayer的setNeedsDisplay这种形式把对NSNode的修改也会提交到全局容器当中
- ASDK在Runllop中注册了一个Observer
- 当RunLoop进入休眠前,ASDK执行该loop内提交的所有任务。
面试题
AFNetworking的整体结构是什么?
绘画模块、网络监听模块、安全模块,核心类是AFURLSessionManager
SDWebImage框架是怎么样加载图片的?
查找内存、在查找磁盘、都没有的情况下去网路下载,
内存的设计是什么?
RAC的信号订阅是什么意思,我们该怎么样去理解?
信号是一连串的状态的抽象,订阅信号就是通过RCASubscriber来实现,传递过去的block作为成员变量保存下来,然后RCASubscriber
在具体的去调用`sentNext这个方法来执行这个block?
ASDK的实现原理?
封装一个NSNode节点,对于视图的属性设置都转化成NSNode的设置而这一部分又可以放入到后台线程线去实现,然后我们在合适的时机,也就是在RunLoop结束的时候接收一个通知,提取全局容器当中的对应的NSNode然后在一次性设置UIView,这个就是ASDK的实现原理。