iOS扩展iOS面试题

ios - 分享交流会总结(一)

2019-01-30  本文已影响178人  tigerAndBull

前言

来自公司内部的分享交流会,
简单地做个总结,并进行一些扩展和思考。

目录

  • 封装相关
  • block,delegate,notification三者优缺点
  • 缓存机制

封装相关

封装大致有两种,一种是组件化,另一种是模块化
组件化:主要是针对某类问题的解耦和复用,可以理解为一个工具箱
典型:Masonry,MJRefresh,AFNetworking等优秀开源库

模块化:主要针对业务模块,将同一类功能进行业务解耦
例如:登陆注册模块,内购模块,直播模块等

  1. .h的设计:对于.h中接口,属性,协议等的设计要提前考虑清楚,建议将最终想要达到的理想效果写好,这样能减少在封装过程中,多次调整.m的痛苦。
  2. 接口的可读性,最好的状态是开发者看了接口名,便大致知道这个接口的作用
  3. 封装粒度,对于每一个细小的功能都可以抽象成一个函数,大的功能由小的功能点逐级累加出来,这样做的好处是易于维护

例如:

- (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];
}
  1. 在版本迭代过程中,向下兼容的必要性。
    对于解决较于庞大的问题,多数情况下在前期都不能考虑的特别完善或者因为系统版本的变更,不得不做出接口的调整。
    废弃的接口,建议利用NS_DEPRECATED_IOS,制造编译器警告,提醒开发者及时更换
  2. 其他:在封装时必须要提高程序的容错率,测试也要详细,这也很考验一个程序员的功底

block,delegate,notification三者优缺点

1. block:

优点:使用简单,代码耦合度低,多用于单一事件的处理
缺点

  1. 超过两种状态情况下,用同一block可读性会变得稍差
  2. 当事件的通信状态需要进行重置时,封装库的人需要另开接口,开发者则需要写额外的代码重置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目录,系统会对该目录清理

本人由此的思考:请求网络数据的缓存框架

上一篇 下一篇

猜你喜欢

热点阅读