这个帖子整理我遇到过的iPhone App Crash类型以及解决办法。Crash原因有很多,不同技术所导致的Crash会不同。整理出来的经验应该会相对片面,有错误的地方和任何问题,请毫不犹豫的指出。 保证App持续稳定运行是非常必要的,开发人员应该把维护产品稳定性、提高产品性能意识融入到每次编写代码过程当中,这也是很多公司考察优秀开发人员的一个重要环节。 Crash原因 Crash原因有共性,归纳起来有: • 内存管理错误 • 程序逻辑错误 • SDK错误 (部署版本< 编译版本) • 主线程阻塞 内存管理错误 内存管理是iPhone开发所要掌握的最基本问题,特别是使用引用计数手动管理内存的情况。内存管理错误包括: • 内存泄漏:未释放不会再使用对象。比如alloc忘记release,malloc忘记free。可用XcodeProduct菜单下的Analyze功能来解决该问题; • 引用出错:引用已经被释放的对象指针。很多“莫名其妙”的Crash都是由于窗体经历的生命周期所导致的(viewDidUnload、viewDidLoad),在iOSSimulator里模拟内存警告就可以解决该问题; • 内存警告:App使用的内存超出设备的限制,iOS将强制挂起App,强制挂起iOS是不会记录Crashlog,Flurry也无法记录。内存泄漏、快速/大量的分配内存都可能导致内存警告,这时候应该尽可能的释放不需要的资源。通过Instruments->Allocations里的Heapshot功能能够找出哪些资源未被释放。 WWDC 2012的Session242 - iOS App Performance_ Memory是专门讨论内存管理这个话题。 程序逻辑错误 数组越界、堆栈溢出、并发操作、逻辑错误。扎实的编码基础、严谨细致的工作习惯、清晰的思路可以避免这类错误; SDK错误 这个错误出现的现象是有的设备运行正常,有的会Crash。原因是未找到框架、类、方法、属性。比如:用iOS5.0 SDK编译并运行在iOS4.0的设备上,5.0的Twitter框架在4.0的设备上找不到。这种问题常出现在用苹果新发布的Xcode编译原有的工程。 未找到框架的解决办法是:部署版本>= 编译版本。iOS框架向后兼容做的很棒,部署版本> 编译版本一般不会出现问题。 未找到类、方法、属性的解决办法是:先判断是否存在再使用 if(NSClassFromString(@"MFMailComposeViewController")) respondsToSelector: 主线程阻塞 主线程阻塞超过10s,iOS将强制挂起App。把长时间的任务放到后台线程去执行,可使用NSThread,NSOperation, dispatch。WWDC2012的Session235 - iOS App Performance_ Responsiveness有详细的介绍。 解决Crash 思路是:定位Crash的程序代码,预测Crash原因,寻找解决方案,测试。 有多种方式可以定位Crash的程序代码: • Debug模式时,iOSSimulator断点测试定位Crash的堆栈; • 真机连接iTunes查看Crashlog (Debug模式下); • 通过Flurry的错误记录查看; 定位之后,就是重新思考程序上下文逻辑,并有理由的预测Crash出现的原因。预测的越多,理解的越深。 寻找解决方案的方法有: • 浏览苹果官方SDK文档,找出错误原因; • Google搜索Crash输出的信息,重点查找行业内技术论坛:cocoachina、stackoverflow、iphonedevsdk等; • 查看历届WWDC的视频、示例代码; • 在工程里添加环境变量: NSZombieEnabled、NSDebugEnabled,输出有价值的信息; • 如果未找到任何信息,可以寻求苹果官方论坛、业内技术论坛的帮助; 测试 找到解决方案后就需要测试,测试功能输入输出的准确性、程序性能、是否引入新的bug。测试有专业的测试工程师来负责,但开发工程师不能依赖测试工程师来发现问题,尽量独立解决已知存在的问题。 由于Xcode部署工程到真机上比较耗时间,如果可以的话尽可能用iOSSimulator来测试,以减少测试的时间。 建议开发工程师有一个checklist,在产品测试时自己逐一过一下上面常见的问题,这个能够避免大部分Crash。下图是我们一个产品的FlurryError记录,那120个错误Session是测试Crash时留下的。当然这个记录是没有包括iOS将强制挂起App的情况。 |
iPhone App Crash的类型以及解决崩溃办法
最新推荐文章于 2024-07-20 09:27:24 发布