ios - 分享交流会总结(一)
前言
来自公司内部的分享交流会,
简单地做个总结,并进行一些扩展和思考。
目录
- 封装相关
- block,delegate,notification三者优缺点
- 缓存机制
封装相关
封装大致有两种,一种是组件化,另一种是模块化
组件化:主要是针对某类问题的解耦和复用,可以理解为一个工具箱
典型:Masonry,MJRefresh,AFNetworking等优秀开源库
模块化:主要针对业务模块,将同一类功能进行业务解耦
例如:登陆注册模块,内购模块,直播模块等
- .h的设计:对于.h中接口,属性,协议等的设计要提前考虑清楚,建议将最终想要达到的理想效果写好,这样能减少在封装过程中,多次调整.m的痛苦。
- 接口的可读性,最好的状态是开发者看了接口名,便大致知道这个接口的作用
- 封装粒度,对于每一个细小的功能都可以抽象成一个函数,大的功能由小的功能点逐级累加出来,这样做的好处是易于维护
例如:
- (void)sd_setImageWithURL:(nullable NSURL *)url {
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
}
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
}
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
}
- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
}
- 在版本迭代过程中,向下兼容的必要性。
对于解决较于庞大的问题,多数情况下在前期都不能考虑的特别完善或者因为系统版本的变更,不得不做出接口的调整。
废弃的接口,建议利用NS_DEPRECATED_IOS
,制造编译器警告,提醒开发者及时更换 - 其他:在封装时必须要提高程序的容错率,测试也要详细,这也很考验一个程序员的功底
block,delegate,notification三者优缺点
1. block:
优点:使用简单,代码耦合度低,多用于单一事件的处理
缺点:
- 超过两种状态情况下,用同一block可读性会变得稍差
- 当事件的通信状态需要进行重置时,封装库的人需要另开接口,开发者则需要写额外的代码重置block
注意点:循环引用
针对第二条的案例:
/**
开启下载任务
@param url 下载地址
@param fileName 下载文件保存名字
@param progressBlock 下载进度回调 在子线程中 需要主动放入主线程操作
@param stateBlock 下载状态回调 在子线程中 需要主动放入主线程操作
*/
- (void)download:(NSString *)url
fileName:(NSString *)fileName
progress:(void(^)(NSInteger receivedSize,NSInteger expectedSize,CGFloat process))progressBlock
state:(void(^)(DownloadState state))stateBlock;
/**
重置下载状态动画
@param progressBlock 下载进度回调 在子线程中 需要主动放入主线程操作
@param stateBlock 下载状态回调 在子线程中 需要主动放入主线程操作
@param url 下载地址
*/
- (void)setProgressBlock:(void(^)(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress))progressBlock
state:(void(^)(DownloadState state))stateBlock
withUrl:(NSString *)url;
说明:当使用第一个接口开启下载任务,并进行UI的刷新,这个时候退出当前controller并释放,重新进入controller时,则需要使用下面的接口对block的状态进行重置,这个时候用delegate或者通知更优
2. delegate:
优点:注重一个事件过程信息的传递
例如网络请求:即将开始网络请求 — 开始网络请求 — 请求成功,接收到数据 — 处理数据成功
缺点:切换代理代价大,使用繁琐
注意点:weak修饰
引出delegate用weak和assign修饰的区别:
assign:对于某个用assign修饰的成员变量B赋值某对象A的指针,则B只是保存此指针的值,并不持有对象A,也就意味着如果A被销毁,则B就指向了一个已经被销毁的对象,如果再对其发送消息会造成野指针
weak:weak本身也是不持有对象的,但是会在对象释放的时候,自动置为nil
区别场景:
假设 self 为 UIViewController
如果tableView同时被其他地方引用,
当viewController释放时,tableView并不会释放,
此时如果是用assign修饰则会造成野指针,而weak是安全的
self.tableView.delegate = self;
3. 通知:
优点:应用于一对多,多对多的场景较突出
缺点:始终不清楚通知是否发送成功,是否发送正确,安全性有所欠缺
PS:KVO的原理其实就是使用了通知机制
缓存机制
适当的缓存对系统效率大大提高,提到weak表,注册表等概念,由于时间关系,没有进行深入探讨
示例:
- 热点数据使用缓存数据库存储
- SDWebImage的缓存原理类似缓存数据库的key,value,存储在应用沙盒cache目录,系统会对该目录清理
本人由此的思考:请求网络数据的缓存框架