概述
项目结构和架构
1.项目结构
项目结构分为两大类,第一为项目中所使用的文件目录分类,第二为项目中使用的第三方库
项目文件目录分类
总体设计思路将项目的目录分为业务模块,功能模块,配置文件模块对业务模块采用MVC的设计模式;
业务模块:项目内有有几大业务模块就分几类,绝大部分项目都可以按照tabbar来划分业务模块,然后增加注册登录等,这就构成了业务模块,对每个业务模块采用MVC模式.
功能模块:项目内所引用或者使用的功能模块,这块按照不同功能模块类进行细分,例如可以细分为分类、公共的UI组件,Utils文件(其中Utils文件可以包含网络,加密,common等文件)等等.
配置文件模块:存放pch文件,常量,宏定义等全局共用的文件.
可以用下图表示:
项目第三方库
优先推荐采用cocopods管理项目所引用到的开源库和私有库.
2.项目架构
项目逻辑基本都围绕了一条主线时,我们采用MVC已经可以很好的满足我们的需求,但是当业务逻辑日渐复杂的时候,我们单纯的采用Model View Controller这种编程模式已经不能很好的将业务逻辑与代码分离开,也就是解耦Decouple.
为了更好的将ViewController解耦,产生了Model View ViewModel这种编程模式,ViewModel层其实做了一层Model与ViewController中间的桥接,有利有弊,该模式会产生很多胶水代码,但是配合响应式编程框架(如ReactiveCocoa或者RxSwift),可以做到最大程度的解耦。适合与自己实际项目业务复杂程度的模式才是好的编程模式
如果项目业务很复杂、很多业务组件都通用,可以采用组件化编程,常用的一种就是采用CocoaPods将项目业务模块分拆成各种pod库,使用什么模块直接集成就好,再配合MVVM和响应式编程框架(如ReactiveCocoa或者RxSwift),可以做到最大程度的解耦。蘑菇街的组件化设计思路可以借鉴参考:https://www.cnblogs.com/oc-bowen/p/5885476.html
程序健壮性
..
1.在框架层面提供运行稳定性
加强单位测试的重要性,单元与单元之间不具有强烈耦合性,合适运用MVC,工厂模式,等设计方法,封装,集成和多态的面向对象的思想,这些均是程序在框架层面的控制,虽然简单,但意义重大,可保证每次批量用例执行时,整体上的稳定可.
2.在细节层面上的技巧提高健壮性
属性修饰符的正确使用,对于类不同的属性选用合适的修饰符;
合理布局函数的返回值,保证函数的值一直;
必要情况下使用Try…Except…处理;
从运行时角度出发,对可能存在的异常做消息转发等操作;
细节层面上的东西很多,在此只列举1,2,还需在开发中总结积累.
3.清理代码,去除冗余代码
很多时候,我们的代码都是迭代开发的。往往会罗列一些无用的函数,引入一些无用的类库。这些内容貌似无意义,但却是代码中的隐患。可能在后续的类库更新或者函数变更中爆炸。所以,代码要保持清理,对于无用的引用和定义,要加以清除。
崩溃处理
1.检测上传崩溃信息
利用友盟, bugly等第三方统计,或者自己编写的一套崩溃方法,上传崩溃日志,以便于对崩溃现象进行分析,改正.
- 针对崩溃现象的处理
通过使用NSSetUncaughtExceptionHandler注册自己的异常处理回调,发生崩溃时让程序显示的从容一点,不会直接闪退,可以弹出自己的崩溃异常界面,可以参考Bilibili的界面,比如说前方遇到高能反应之类,程序需要重启之类的,不会让用户感觉到很突兀得闪退了,也可以在收到崩溃日志后手动维护Runloop. 下面是一个样例.
// 1. 注册ExceptionHandler
+ (void)installUncaughtExceptionHandler {
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGHUP, SignalHandler);
signal(SIGINT, SignalHandler);
signal(SIGQUIT, SignalHandler);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
}
// 2. 处理崩溃信息
void SignalHandler(int signal) {
// 1. 获取调用栈
// 2. 处理异常
// 3. App保活
BOOL isContiune = TRUE; // 是否要保活
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
while (isContiune) {
for (NSString *mode in (__bridge NSArray *)allModes) {
CFRunLoopRunInMode((CFStringRef)mode, 0.001, true);
}
}
CFRelease(allModes);
signal(SIGABRT, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
}
2.利用热修复进行动态bug修复
在工程中集成JSPatch,实现热修复功能
APP性能调优,体验优化
1.懒加载的合适使用
懒加载适用于一些可能不会加载的页面,比如弹框、空数据页面之类的,使用得当可以避免内存暴涨,使用不好,比如在必定会弹出的页面中使用懒加载可能会在增加页面响应时间,所以使用懒加载一定要注意使用场景,避免产生副作用.
2.避免使用重绘
重写drawRect 或者drawReact:inContext方法会默认创建一个图层上下文,图形上下文所需要的内存为图层宽* 图层高* 4字节,图层每次进行重绘时都需要抹掉内存重新分配,会产生巨大的性能开销
3.用户体验
UITableViewCell 使用不当造成滑动卡顿;
减少cornerRadius,maskToBounds诸如造成离屏渲染的方法的使用;
网络请求操作没有任何状态展示,比如加载框、按钮置灰等;
网络请求设置合理的缓存策略;
4.内存管理
合理使用属性修饰符,避免僵尸对象和野指针的产生;
利用aoturealese来降低内存峰值;
利用instrucment的leak来检测是否存在内存泄露等问题;
减少诸如imageNamed这类将导致内容永驻方法的使用;
内存管理要注意的地方很多,此处只列举一二.
5.选择合适的数据存储项
针对不同的应用和用户数据采用不同的数据存储,具体的数据存储选项如下:
NSUerDefaults, 使用XML, JSON, 或者plist, 使用NSCoding存档, 使用类似SQLite的本地SQL数据库, 使用Core Data;
同时对于数据存储位置也要合理选择,对于不用用处的数据存放在document,library,cache中的位置要明确.
6.加速启动时间
应用启动时尽可能做更多的异步任务,比如加载远端或者数据库数据,解析数据;
同时在预加载pch文件中减少引用;
去掉不必要在启动过程中执行的业务和操作.
7.关于webView的使用
减少使用Web特性,尽量使用WKWebView来替代WebView的使用;这样能极大的降低内存消耗.
8.合理运用多线程
合理运用多线程来提交运行效率,避免主线程阻塞.
其他方面
- 减少大量的第三方SDK的使用,尤其是臃肿庞大的SDK;
- 包上线时检查开发过程中弃用的图片资源,冗余代码,减少包体积;
- 项目中使用的图片在满足需求的条件下,尽量缩减存储大小;
- 通过编译项的选择减少包体积;
最后
以上就是魔幻老师为你收集整理的iOS APP优化项目结构和架构程序健壮性崩溃处理APP性能调优,体验优化其他方面的全部内容,希望文章能够帮你解决iOS APP优化项目结构和架构程序健壮性崩溃处理APP性能调优,体验优化其他方面所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复