// 1. cell图片异步加载优化
/** 我的看法:
* 1> 在加载图片时,肯定会有很多下载操作,但是在这些操作里,有很多已经不在屏幕上,因此要
注意合理的取消或暂停操作,等再次回到的时候,重新从待完成操作中,拿出操作重新加载。
* 2> 第一次加载图片时,应该检测是否有缓存存在,比如内存缓存、沙盒缓存中,同时,要合理的
清理缓存,比如按时间、按大小、按警告等等。(其实每次被访问的图片都应该合理把它拿出
来放到数组的前面,如果是字典缓存,则不需要)
* 3> 如果都没有缓存,则查一下正在下载操作字典,如果存在,则合一就好,等待下载完成
* 4> 如果没有下载操作,则重新创建一个此url的操作,并将其缓存在下载字典中
* 5> 下载完图片后,进行解码、解压,然后缓存起来,并显示在屏幕上
*/
// 2. 优化cell的高度计算
/** 我的看法:
* 1> cell的高度是在所有cell都没创建之前,就已经一次性算好,还是每滑动一次就计算一次?
* 2> 当你设置估算高度后,当tableView显示出来时,按估算高度显示tableView
* 3> 后面根据你滑动,然后按每一个cell的高度来设置tableView的高度,能够让tableView可
以滑至底部。
* 4> 这里的每一次滑动时,高度的计算可以运用runloop来设置,比如,tableView在滑动时,
runloop处于滑动模式,那其他模式下的代码则暂停或再异步处理,因此我们可以在滑动时,
利用model的默认模式,让它在此模式下,计算高度,则可以提升性能和效率,方式是[self
performSelector]
*/
// 3. 关于设置圆角的离屏渲染问题
/** 1> 在一个页面上,如果没有使用maskToBounds,并且圆角radius在10个左右,则基本对性能损伤不大,但我建议,还是尽量不要使用radius和maskToBounds来设置圆角
* 2> 同事不要采用drawInRect来设置圆角,因为如果上下文的大小比较大时,所占用的内存很大
* 3> 采用core graphics和贝塞尔曲线来绘制圆角,添加在图层上
*/
// 4. 优化产品性能、安全加固、保证app安全、稳定、快速运行、省电/省流量
/** 我的看法:
* 1> 优化产品性能: 优化产品的性能主要在tableView上,也就是不要出现离屏渲染、大图片尽
量显示跟控件大小一样尺寸的缩略图,图片的解码、解压等可以做预渲染处理、cell的层次结
构不要太复杂,如
果出现有复杂的cell,可以通过一次性创建出来,并做隐藏处理,cell的高度可以放在
runloop的另一个model下处理和计算。
* 2> 安全加固: 安全加固可以采用native和js、html的方式写应用,同时,还具备热更新功能。
* 3> 保证app安全: app的安全主要体现在网络层,也就是网络请求,每次网络请求希望都带上
uuid + 密钥 + 盐 再 md5 处理,这样别人截取了网络层的url也无法访问服务器。
* 4> 稳定: 利用instrument进行性能优化管理,并加上奔溃日志提前发送至邮箱排查崩溃,或者
友盟sdk崩溃日志等
* 5> 快速运行: 尽可能的使用多线程和并行技术,把耗时的操作放入后台处理
* 6> 省电/省流量: 用instrument检查功耗,同时把一些后台操作尽可能优化,加载网络缩略
图,而不是高清图,如果是流量状态,提醒是否播放视频。
*/
// 5. AFNetworking的内部实现原理是什么?
/** 我的看法:
* 1> 最关键的一个问题就在于NSURLConnection下载完成前,线程结束,导致delegate接受不到回调的问题。
* 2> 解决这个问题的关键因素就是利用runloop,新建一个NSThread,并且开启runloop
* 3> delegate的回调就在这个runloop当中接收
*/
// 6. runloop的简单应用
/** 我的看法:
* 1> 比如上述情况
* 2> imageView 在 setImage 时,利用[self performToSelector inModel:@[NSDefaultRunLoopModel]]
* 3> 设置tableView的高度是利用runloop
* 4> 默认除了主runloop,其他runloop都是默认不开启的,需要主动获取,然后开启runloop,线程和runloop是一一对应的
*/
// 7. 性能优化(主要指电量、流量)
/** 我的看法:
* 1> dispatch_block_create_with_qos_class生成的block任务操作,会对电量进行优化
* 2> 避免线程爆炸,比如:使用串行队列或者dispatch_apply或者信号量 + wait,NSOperation限定当前最大的并发数
* 3> i/o性能优化:
* 一:将零碎的内容作为一个整体写入
* 二:使用合适的i/o操作api
* 三:使用合适的线程
* 四:NSCache做缓存,能减少i/o
* 4> 控制app被唤醒的次数,比如定位、VoIP、通知、蓝牙等等,用比较合适的api,比如定位有一个持续定位功能,要不需要定位的时候应
该立即关闭
* 5> 内存对性能的影响,比如大量内存需求是比较影响性能的
* 6> 主要预防性能方法:
* 一:优化计算的复杂度,从而减少CPU的使用
* 二:在应用交互的时候,停止不必要的任务响应
* 三:设置合适的Qos
* 四:将定时器任务合并,让cpu有更多的时间处于空间状态
* 7> 通过在main runloop里添加observe来,监听影响响应的操作。比如,创建一个observe,然后设置model为common,然后监听
runloopActivity的回调,然后在回调里创建子线程,在子线程里,通过semaphore_wait来设置时间,一般是16-20微妙。主要监
控结果的两个状态是beforeSources和afterWaiting,在此区间内能否检测到,来判断卡顿
*/
// 8. 深入理解GCD
/** 我的看法:
* 1> GCD主要涉及两个概念,一个是同步、异步操作,一个是队列
* 2> GCD当中,同步的意思是顺序执行,异步的意思是并发执行
* 3> 队列分为串行队列和并行队列,其中串行队列的意思FIFO,并发队列是随机,就是它会把里面的任务block分到合适的线程中去执行
* 4> iOS给我们提供了一个main队列,一个全局队列,这里面全局队列一定要使用默认优先级,否则会出现资源共享的错误
* 5> 我们还可以通过create创建一个concurrent队列和serial队列,这里除了concurrent队列是并发队列,实际上serial和NULL是
一样的
* 6> GCD一共为我们提供了barrier(只有在自己创建的并发队列上才有效,放入全局队列中,相当于串行,所以要小心死锁)、apply、
group、semaphore、once、after、async、sync、suspend、resume技术等
* 7> 还有一个建议就是block,在dispatch当中,当计算量比较大,i/o比较耗时等情况下,使用
dispatch_block_create_Qos_class,这个block会对性能、耗电进行优化
* 8> 还有block操作在GCD中,大部分是线程安全的,一般无参数、无返回值的block在GCD里都是安全的,源代码表明,它会将block进行
copy和release一次,所以在GCD中,对block是否会造成循环引用的情况,可以先看下源代码,这个是开源的
* 9> 尽可能的多使用GCD,会合理利用多核,合理开启、关闭多线程
* 10> 这里还有一个GCD线程池的概念,就是不管是你自己创建的queue、还是使用系统的全局队列最后都会通过全局队列,将它放入线程
池,等待调度
*/
// 9. 项目经历
/** 我的看法:
* 1> 那我就简单说说我上一个项目吧,我上个项目主要是面向国外的一个类似于一元抢购的app,采用了不局限于mvc、mvvm的架构模式,主
要是分层的思想,数据的流动和格式化
* 2> 首先app一开始进入,会有一个启动图,我当时建议的是,所有图片没有alpha通道,并且图片尺寸要跟控件或屏幕等大,@2x,@3x翻
倍即可
* 3> 然后是进去后,如果是第一次登陆或者说打开app,或者更新app后,第一次打开app,则会有一个版本新特性,一般这个功能比较简
单,就是3、4张imageView,然后一个button按钮,我当时是拿出了以前封装好了的一个类,拿过来直接使用,这里实现是主要就是
通过传url数组,可以是网络url,也可以是沙盒url,内部会判断
* 4> 接下来就进入了登录界面,主要是两个textField和忘记密码、注册账号、以及G+登录、facebook登录
* 5> 这里的密码通过rsa加密,并且过程稍微复杂一点,主要是要加点盐、再md5、再base64、再压缩一下
* 6> 短信验证是通过SMSSDK实现的
* 7> 网络安全是通过在url上加上uuid和token以及密钥的md5,确定是本机访问,同时全部都是https请求
* 8> 进入首页后,会弹出一个新用户福利的对话框,这个对话框是根据标识符实现,并且有一个灰蒙蒙的蒙版,再加上一个底下的XX按钮,
以及重要的新用户提示iamgeView,这里的imageView的setImage方法采用的是ofFile,而不是named,毕竟只用一次
* 9> 点进新用户提示框后,进入一个卷的领用界面,这个卷的领用之后,会和服务器进行一个双向同步,因此我建了几张表,分别表示待执
行、待同步,在从服务器拉下来后的表和本地的表合二为一,然后再执行同步操作,或者将待同步的操作上传至服务器等等
* 10> 然后返回进入首页,首页是这样设计的,最上面有一个NSTimer定时器,这个会循环引用,后来改为GCD编写的timer
* 11> 就是广告栏、中奖提示栏、4个带圆角的快捷按钮、底下是tableView显示产品
* 12> 广告栏是这样的,其实和版本新特性的实现一样,就是根据url来显示,然后点进去之后也是一个url网页,可以我自己的那个类
* 13> 然后是中奖提示框,这个提示框主要是滚动,一直在滚动,获取最新的中奖人信息,同时,也是GCD实现的timer
* 14> 其中有一个网络层,就是从服务器拉下来的数据是json,也就是NSDictionary,我写了一个自己的networking网络请求类,然后封
装AFN,其次再写一个业务网络类,每次执行某个业务就调用某个业务接口,屏蔽一些细节,然后将拿到的json通过自己为每一个请求
添加的refer类,将其在需要的时候,调用这个方法转化为view能直接用的数据,而不单单是model,这样能增加测试、重用、分层的
效果,同时也说明了,在用的时候才转化的一个,有点类似懒加载思想,我觉得还可以不单单只是一定要转化为模型,直接用
NSDictionary也行,类似于UIKit当中的一些key作全局或静态处理即可
* 15> 然后是4个带圆角的快捷按钮,这里圆角不一定会造成丽屏渲染,主要是圆角多、同时将maskToBounds设置为yes后,因为需要多重混
合就会造成离屏渲染,这里的圆角设置采用的方法有两种,一种是core graphics自己画,这里不建议使用drawInRect方法,第二种
是直接采用圆角图片,直接让UI做一张
* 16> 接下来是tableView的商品介绍,其中,tableView拉上来后,会直接将tableView充斥全屏,主要采用了height和frame的设置,
用一个标识符判断
* 17> 每个cell都有一个添加到购物车的动画,这个动画一开始是用UIView,后来发现又要旋转、抛物线、变小,就采用了core
animation技术,就是直接对图层进行动画处理
* 18> tableView的性能优化采用了runloop的两个处理,一个是在拖动的时候,暂停其他任务,一个是在拖动的时候计算其他cell的高度
并且cell的全部内容一次性创建,在一个cell的基础上进行hidden,同时,里面的图片全部没有缩放,控件大小就是图片大小,也利
用了instrument进行了性能和功耗检测
* 19> 点击cell后,进入详情业,隐藏navagationBar...
* 20> 我说架构吧,整体架构主要是mvvm,其次是mvc,我觉得mvc和mvvm本质是一样的,都是数据流动,主要是将model分散一下,分到vm
当中,为c减压,其中vm和v的联系就是响应式编程,也就是rac联系,通过c创建一个桥,subject,联系双方,然后send消息,响
应,做出对应的处理,其中有一些界面太过简单,用mvc也没有导致c很臃肿,主要是分层分的很细,比如c主要是做什么的?主要是做一
个桥梁,响应事件push一下c,想c中的v直接封装一下,让子v去实现具体的细节,而最重要的就是UITableViewController,这个
可以将tableView的dataSource分给其他类来处理,轻化c,有的直接把tableView整个分给vm来处理,这个我觉得不好,主要是
tableView还有一个响应事件需要c来配合,还不如直接放c,只把dataSource分出来,然后就是c的一些业务逻辑可以分给vm处理,
展示逻辑全部是vm,具体情况具体考虑
* 21> 现在重要的是持久层,持久层现在重要的技术就是fmdb,就是建表的一些考虑,数据存储的格式,以及怎么存的方法
*/
网友评论