知识点总结

243 阅读7分钟

1.SDWebImage、AFNetWorking底层原理;

1.SDWebImage工作流程

1、入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。

2、进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:delegate:userInfo:.

3、先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。

4、SDWebImageManagerDelegate 回调 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示图片。

5、如果内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找图片是否已经缓存。

6、根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调 notifyDelegate:。

7、如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。

8、如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调 imageCache:didNotFindImageForKey:userInfo:。

9、共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。

10、图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。

11、connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效果。connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。

12、图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。

13、在主线程 notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo: 回调给 SDWebImageDownloader。imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。

14、通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。写文件到硬盘也在以单独 NSInvocationOperation 完成,避免拖慢主线程。

15、SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。

16、SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。

17、SDWebImagePrefetcher 可以预先下载图片,方便后续使用。

2.AFNetWorking底层原理;

参考:www.shangmayuan.com/a/47401f001…

2.OC内存管理

参考1:www.jianshu.com/p/0d7dfb509…
参考2:www.jianshu.com/p/22031a104…
内存五大区:www.jianshu.com/p/e5a54813b…

3.KVC、KVO实现原理

参考:www.jianshu.com/p/aab515490… zhuanlan.zhihu.com/p/159206464

4.MVC、MVVM设计模式;

参考:blog.csdn.net/yimumian/ar…

mvvm设计模式

image.png

    1. model(数据模型),view(视图),viewmodel(视图模型)
    1. 大家可以看到,里面是没有controller了,但是他将viewmodel代替了controller。在运行过程中起了view和 model的链接桥梁,但是又有一点区别与mvc的是,mvc中被动接受view请求的controller在这里,viewmodel给他做了升级,不再是被动接受,而是不断监听view,当有新的需求时,就去链接model拿去数据,然后返回给页面,很好的将view和model做了分离,使view和viewmodel可以独立完成开发。
    1. 缺点:不断的监听页面,性能消耗很大

mvc和mvvm的区别

    1. mvc中controller是被动接受请求,而mvvm中作为控制器这一环节的是主动地。
    1. mvc中view可以直接访问model,因此view中必然包含了业务逻辑,并没有实现view和model的分离,而mvvm主要是通过数据的双向绑定机制,在js中实现业务逻辑,进行view和model的关联,因此mvvm真正意义上实现了view和model的分离。

5.runtime、runloop

1.讲一下 OC 的消息机制

  • OC中的方法调用其实都是转成了objc_msgSend函数的调用,给receiver(方法调用者)发送了一条消息(selector方法名)
  • objc_msgSend底层有3大阶段
  • 消息发送(当前类、父类中查找)、动态方法解析、消息转发

2.什么是runtime

  • OC 是一个全动态语言,OC 的一切都是基于 Runtime 实现的平时编写的OC代码, 在程序运行过程中, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者 比如:
OC :
[[Person alloc] init]
runtime :
objc_msgSend(objc_msgSend("Person" , "alloc"), "init")
  • runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API
  • runtimeAPI的实现是用 C++ 开发的(源码中的实现文件都是mm),是一套苹果开源的框架

3.runtime具体应用

  • 利用关联对象(AssociatedObject)给分类添加属性
  • 遍历类的所有成员变量(修改textfield的占位文字颜色、字典转模型、自动归档解档)
  • 交换方法实现(交换系统的方法)
  • 利用消息转发机制解决方法找不到的异常问题

Runloop

RunLoop运行流程

没有事情的时候,Runloop处于休眠状态。当外部source将其唤醒后,它会依次处理接收到的timer/source,然后再次进入休眠。

一个Runloop可能有几个mode

  1. 指定事件在运行循环中的优先级的
  2. 线程的运行需要不同的模式,去响应各种不同的事件,去处理不同情境模式。(比如可以优化tableview的时候可以设置UITrackingRunLoopMode下不进行一些操作,比如设置图片等。)

Runloop Mode 实际上是 Source,Timer 和 Observer 的集合,不同的 Mode 把不同组的SourceTimerObserver隔绝开来。Runloop` 在某个时刻只能跑在一个 Mode 下,处理这一个 Mode 当中的 Source,Timer 和 Observer。

苹果文档中提到的 Mode 有五个,分别是:

NSDefaultRunLoopMode:默认的mode,正常情况下都是在这个mode
NSConnectionReplyMode
NSModalPanelRunLoopMode
NSEventTrackingRunLoopMode:使用这个Mode去跟踪来自用户交互的事件(比如UITableView上下滑动)
NSRunLoopCommonModes

iOS 中公开暴露出来的只有 NSDefaultRunLoopMode 和 NSRunLoopCommonModes。 NSRunLoopCommonModes 实际上是一个 Mode 的集合,默认包括 NSDefaultRunLoopMode 和 NSEventTrackingRunLoopMode

Source

即可以唤醒Runloop的一些事件。比如用户点击了屏幕,就会创建一个input source。

  • source0 : 非系统事件
  • source1 : 系统时间

Timer

我们经常用的NSTimer就属于这一类。

Observer

某个observer可以监听runloop的状态变化,并作出一定反应。

image.png

什么是Runloop

Runloop是事件接收和分发机制的一个实现。是线程相关的基础框架的一部分。一个Runloop就是一个事件处理的循环,用来不停的调度工作及处理输入事件。使用runloop的目的就是让你的线程不会被系统终止

RunLoop的主要目的:

保证程序执行的线程不会被系统终止,如果没有RunLoop,UIApplicationMain函数执行完毕之后将直接返回,就是说程序一启动然后就结束,在有工作的时候忙于工作,而没有工作的时候处于休眠状态,

Runloop和线程是什么关系?

每条线程都有唯一的一个与之对应的RunLoop对象;主线程的RunLoop已经自动创建,子线程的RunLoop需要主动创建;RunLoop在第一次获取时创建,在线程结束时销毁

什么时候使用Runloop ?

当需要和该线程进行交互的时候才会使用Runloop.

RunLoop处理消息的流程是“接收消息->恢复活跃->处理消息->进入休眠”。

RunLoop怎么用?

1.NSTimer中底层用到了RunLoop。
2.Autorelerasepool也是用了RunLoop的原理进行内存的回收
3.创建NSTimer的时候,也是用到了RunLoop,performSelecter:afterDelay使用时。
4.事件的交互,触摸屏幕或者硬件的交互,也用到了RunLoop。
5.UI界面刷新。
6.调用了dispatch_async(dispatch_get_main_queue(), block)时,主队列会把该 block 放到对应的线程(恰好是主线程)中,主线程的 RunLoop 会被唤醒。
7.AFNetWorking 3.0以前的线程保活。
8.可以用来监控系统卡顿。

6.Https

https.png

7.Block

参考1:www.jianshu.com/p/4e79e9a0d…
参考2:www.jianshu.com/p/0a555501a…

学习:www.jianshu.com/p/5afb47cf5…

8.多线程(GCD、NSThread)

GCD参考:www.jianshu.com/p/2d57c7201…
NSThread参考:www.jianshu.com/p/9ae8e7a18… 线程间的通信:cloud.tencent.com/developer/a…
常驻线程:blog.csdn.net/u012094456/… 线程与进程关系:blog.csdn.net/u012094456/…

9.锁

八种锁:www.jianshu.com/p/8b8a01dd6…
简介及使用:www.jianshu.com/p/af7ff3862…
锁的原理:www.jianshu.com/p/494629e92…

10.组件化解决方案

组件方案:www.jianshu.com/p/7ca16c92c…
组件通信:www.jianshu.com/p/1f10795c9…

组件化通讯方案

目前主流的主要有以下三种方式:

  • 1、URL路由
  • 2、target-action
  • 3、protocol匹配

11.dyld

参考:www.jianshu.com/p/ee6a8ebc5…

12.优化

性能优化:
界面优化:www.jianshu.com/p/5c83da126…

13.视觉效果

视觉效果处理:www.jianshu.com/p/5445fb11e…