iPhone的崩溃日志可以如何删除iphone照片吗?

查看: 15972|回复: 18
彻底删除iPhone4的开机启动项和语言,让你的手机流畅无比。
本帖最后由 洋少爷 于
14:28 编辑
清理不必要的软件和开机启动项
注:看准了,别删错了,本人在iOS5就删除了,一点问题没有。删除这些完全是个人愿意,有没有必要删除处决于自己,乱喷的都去屎,好东西分享出来很不错了,再这样下去,没人愿意分享好东西了,请喷子自重。(删除错误导致的请不要来问我,谢谢。记得看准了先备份原文件再删除也可以,我是这么做的。)
删除多余的启动项,路径:打开【第三方软件&&个人建议iTools 】,进入【文件管理】,然后再【越狱系统】里面找到 /System/Library/LaunchDaemons。
1. com.apple.DumpPanic.plist -这是苹果公司用来评估系统崩溃的,删.
2. com.apple.DumpBasebandCrash.plist -这是苹果公司用来苹果基带崩溃的,删
3--8. ReportCrash -有6个带&ReportCrash&的&.plist&文件,都是用来收集系统或系统程序崩溃的信息,删
9. com.apple.CrashHouseKeeping.plist -也是和程序崩溃相关的,删.
10. com.apple.powerlog.plist -用来监测第三方不兼容的充电器,删.
11.com.apple.chud.chum.plist -如果你不是一个软件开发者,删
12. com.apple.chud.pilotfish.plist -.如果你不开发苹果软件,删.
13. com.apple.mobile.profile_janitor.plist – 收集整理崩溃数据的,删
15. com.apple.datamigrator.plist -这个进程的作用是把联系人从你的SIM卡传到你的iPhone里.删
18. com.apple.AOSNotification.plist -这是同步iCloud用的.不用iCloud的人,考虑.
19. com.apple.aslmanager.plist 管理系统日志文件,删.
20. com.apple.syslogd.plist -记录系统日志,删
21 com.apple.searchd.plist 删除21、22这两个后只是令搜索栏失效,但并不会让搜索栏消失,到cydia安装nospot彻底关闭。省大量内存!
22 com.apple.search.appindexer.plist 同上
23 com.apple.VoiceOverTouch.plist 语音控制
24 com.apple.voiced.plist siri、语音控制均有关
25 com.apple.mobile.obliteration.plist :禁用此服务将使设置里的抹掉所有内容不可用.建议删除这个服务,防止别人不小心或者手贱点到造成白苹果!删!
27 com.apple.printd.plist 空中打印进程,删
28 com.apple.marcoagent.plist 为WiFi连接错误(连接失败)的日志报告进程。对于我们用户来讲,删
29 com.apple.mobile.installd.mount_helper.plist 删除后不影响你用任何方式安装软件及应用!删!
30 com.apple.mobile.storage_mounter.plist 该进程是苹果在未来设备及固件中开启的新功能,将允许你使用你的iPhone保持在“磁盘模式”。也就是相当于一块移动硬盘来使用,不过,在目前的固件中暂时不执行任何操作,因此可以安全地删除这一并未投入使用,且未来也未必会投入使用的“功能”,删!(其实这个也没有必要删除的。)
31 com.apple.AddressBook.plist –旧系统与通讯录载入速度有关,但对于iOS5删!
32 com.apple.appsupport.cplogd.plist -记录应用程序和第三方程序崩溃日志,删
34 com.apple.crash_mover.plist - 移动崩溃日志文件.删
35 com.apple.mobile.softwareupdated.plist –删后,在 设置-通用-软件更新,那里失去检测固件升级的能力,删
36 com.apple.OTACrashCopier.plist - 把OTA崩溃日志移动到,删
37 com.apple.OTATaskingAgent.plist - 通知系统进行ota升级,不需要OTA自动更新的,删
38 com.apple.softwareupdateservicesd.plist - OTA升级服务,不需要OTA自动更新的,删.
39 com.apple.Springboard.SetupHelper.plist - IOS安装向导,只在刚刷完机或抹掉所有内容和设置时出现,越狱后抹除直接白苹果了,所以这个留着无用,删
40 com.apple.certui.relay.plist - 当你在一个公共网络,safari无法校验一个网站时,会提示这个网站未经过验证,是否继续,如果你不在乎,删
41 com.apple.sharktrace.plist 为开发者准备的崩溃日志,删
42 com.apple.assitivetouchd.plist - 辅助功能里的assitivetouch,可以用Acitvator替代!删
44 com.apple.vsassetd.plist - 还是语音控制服务,siri有关,删(这个好像CDMA里没有)
45 com.apple.daily.plist –协助*35检查是否有固件更新,删46 com.apple.wapic.plist - 记录当wifi连接到含有中文字体热点出错的服务,目前没看到有人用中文名做wifi热点的,删
47 com.apple.itunescloudd.plist - 关于itunes的云/家庭共享服务,删
51 com.apple.iapd.plist,删除后,av线,iphone dock等这些第三方设备将无法使用,但对使用耳机,充电无影响,删
55 com.apple.twitterd.plist - 国外推特相关服务,删除
删除设置中Twitter,NIKE-IPOD,股票,辅助功能,语音控制
完全删除nike :
首先打开/Applications/把里面的nike.app删除。
然后打开System/Library/CoreServices/SpringBoard.app,在里面找到N90AP.plist拉到电脑桌面用写字板打开,然后找到nike-ipod这项,把ture改成false 。 关闭保存 (切记这个CDMA版的里面不是N90AP,而是N92AP,不要弄错了。至少我的CDMA的V版是)
重启后发现设置里面的nike消失了。
完全禁用语音控制
首先打开/System/Library/CoreServices把里面的VoiceOverTouch.app删除。
然后打开/System/Library/LaunchDaemons内把进程com.apple.VoiceOverTouch.plist删除。
最后打开System/Library/CoreServices/SpringBoard.app,在里面找到N90AP.plist拉到电脑桌面用写字板打开,然后找到voice-control这项,把ture改成false。 关闭保存 (切记这个CDMA版的里面不是N90AP,而是N92AP,不要弄错了。至少我的CDMA的V版是)
重启后语音控制功能完全禁止了。
完全关闭辅助功能
首先打开/System/Library/CoreServices把里面的AssistiveTouch.app删除。
然后打开/System/Library/LaunchDaemons内把进程com.apple.assistivetouchd.plist删除。
最后打开System/Library/CoreServices/SpringBoard.app,在里面找到N92AP.plist,打开,然后找到accessibility这项,把ture改成false,关闭保存
重启后,进入设置看看辅助功能不见了。
完全删除自带股票
打开设置中的通知,先把股票在通知中心关闭了
首先打开/Applications/把里面的stocks.app删除。(这里重启后打开设置内的通知,里面还是有股票选项,不用急,请往下看。)
然后打开System/Library/WeeAppPlugins/,把StocksWeeApp.bundle整个文件夹删除。
最后重启看看,已经在通知设置里面消失了。
删除设置中Twitter
首先打开/Applications/Preferences.app,在里面找到Settings.plist,打开,然后把下图中的全部删除:,仔细看清楚,不要删错了:
然后打开/System/Library/Frameworks/目录,将Twitter.framework文件夹删除。
最后声明:本教程是我转来的,但我是实验成功者,证明了CDMA版的iPhone4也是可以的,所以里分享给大家。切记不要删除错误,看清楚再删除,iOS5和iOS6都可以适用。最后告诉大家可以删除系统语言的软件,Cydia里下载iCleaner,这个软件可以删除其他语言和系统的缓存垃圾文件,不要说iOS不需要清理垃圾,那是错误的,任何系统不可能没垃圾文件的。
本帖子中包含更多资源
才可以下载或查看,没有帐号?
之前删过,手机越来越卡。。还是不删了。。.
大家没必要删除,真心劝大家,完全没必要的.
维维有你更给力!
必须要支持一下非常感谢
建议大家不要删这些服务,就这样
删吧。没问题的。还有个fsevend,常驻进程,删掉。。
這個要支持呀,謝謝分享。
到底要不要删啊
&font size=&4&&大家没必要删除,真心劝大家,完全没必要的!&/font&复制代码
&font size=&4&&大家没必要删除,真心劝大家,完全没必要的!&/font&复制代码
其实用处不明显
Powered by虽然大作是有,不过这周总觉得不大爽快。夏天到了,说到夏天大家想到的是什么?WWDC?...
也许我们已经被洗脑了,总觉得无论如何iPad Pro都会出现。但问题是,这样的一款产品出...
Android Lollipop 相对 KitKat 而言是一次伟大的改进,但还有很多改进的余地。我们希...
从iPhone到iPad,再到如今的Apple Watch,哪家厂商可以拿苹果的零件订单,基本上都会...
习惯了,喜欢了,喜欢了,也习惯了。
这与苹果向来一丝不苟的作风不符啊,虽然没质量问题但是求换新。
刘延东在北京中南海紫光阁会见来华访问的美国苹果公司首席执行官蒂姆·库克。
让 iPhone 屏幕泛起水纹,对续航可是个大考验。
《将死之日》(A Few Days Left)是国内制作团队 Orap Games 开发,完美世界代理发行...
作为体育大国,中国在近年来在历届奥运会当中都取得了不错的成绩,尤其是在金牌榜和奖...
足够和高质量的睡眠对于现代人来说成为越来越奢侈的愿望,各种熬夜党、失眠党年纪轻轻...
音乐是一种美好的传递情感的语言,如今市面上的音乐 APP 各有各的特色,虽然目前用户...
端游时代,网易凭借《梦幻西游》《大话西游》系列端游产品裂土封王,而手游时代网易旗...
要说 iOS 平台上的策略战争游戏,我想很多朋友都玩过《欧陆战争》系列吧,EASY 当然也...
这是一款有着非常庞大世界观的奇幻类游戏,超过 100 种敌人以及成千种武器装备,看起...
老牌外设厂商罗技早些时候已经在官网上放出了最新旗舰鼠标罗技MX Master 即将推出的消...
充个电还要数据线,太 low 了。
移动电源表示很不开心,因为它们快失业了。
相信很多人都有这样的疑问,在如今一张照片都达到几M的时代,iPhone 8G 和 16G 容量的...
自从 iPhone 6/6P 问世之后,就有更多的厂商专注于制作轻薄又耐用的手机保护壳,当然...
如果,手机壳变成你的第二屏幕......
酷壳iPhone 6充电版终于正式发售了,它可以在保证iPhone依旧轻巧的前提下,为其提供足...
随着越来越多的用户迁移至iPhone 6,酷能量终于要发布酷壳iPhone6充电版了。
崩溃日志在设置里能禁用吗?
注册时间 最后登录
在线时间118 小时 UID
主题帖子人气
白苹果, 积分 861, 距离下一级还需 639 积分
在pp助手里看到的,有500M那么大,可以不生成日志文件吗?
注册时间 最后登录
在线时间118 小时 UID
主题帖子人气
注册时间 最后登录
在线时间118 小时 UID
主题帖子人气
我擦。每次。都是零回复
注册时间 最后登录
在线时间26 小时 UID
主题帖子人气
不能禁用,你删了不就完了
<p id="rate_37905" onmouseover="showTip(this)" tip="谢谢&人气 + 3
" class="mtn mbn">
注册时间 最后登录
在线时间462 小时 UID
主题帖子人气
积分   -15935
禁用了会提示如图字样。你可以用助手删除日志,但不能禁用启动项
<p id="rate_37905" onmouseover="showTip(this)" tip="谢谢。&人气 + 5
" class="mtn mbn">
威锋旗下产品
Hi~我是威威!
沪ICP备号-1 丨 深公安网监备案号 5
增值电信业务经营许可证:
Powered by Discuz!1. com.apple.DumpPanic.plist -这是苹果公司用来评估系统崩溃的,删.
2. com.apple.DumpBasebandCrash.plist -这是苹果公司用来苹果基带崩溃的,删
3--8. ReportCrash -有6个带"ReportCrash"的".plist"文件,都是用来收集系统或系统程序崩溃的信息,删
9. com.apple.CrashHouseKeeping.plist -也是和程序崩溃相关的,删.
10. com.apple.powerlog.plist -用来监测第三方不兼容的充电器,删.
11.com.apple.chud.chum.plist -如果你不是一个软件开发者,删
12. com.apple.chud.pilotfish.plist -.如果你不开发苹果软件,删.
13. com.apple.mobile.profile_janitor.plist – 收集整理崩溃数据的,删
*15. com.apple.datamigrator.plist -这个进程的作用是把联系人从你的SIM卡传到你的iPhone里.尽管我是iPhone,但我删了它,因为我从来不在SIM卡中存联系人,考虑.
20. com.apple.syslogd.plist -记录系统日志,删
*23 com.apple.VoiceOverTouch.plist & VoiceOver功能,残疾人用的,删
*24 com.apple.voiced.plist siri、语音控制均有关,考虑
25 com.apple.mobile.obliteration.plist :禁用此服务将使设置里的抹掉所有内容不可用.建议删除这个服务,防止别人不小心或者手贱点到造成白苹果!删!
*27 com.apple.printd.plist 空中打印进程, 考虑
28 com.apple.marcoagent.plist 为WiFi连接错误(连接失败)的日志报告进程。对于我们用户来讲,删
29 com.apple.mobile.installd.mount_helper.plist 删除后不影响你用任何方式安装软件及应用!删!
30 com.apple.mobile.storage_mounter.plist 该进程是苹果在未来设备及固件中开启的新功能,将允许你使用你的iPhone保持在“磁盘模式”。也就是相当于一块移动硬盘来使用,不过,在目前的固件中暂时不执行任何操作,因此可以安全地删除这一并未投入使用,且未来也未必会投入使用的“功能”,删!
31 com.apple.AddressBook.plist –旧系统与通讯录载入速度有关,但对于iOS5删!
32 com.apple.AdminLite.plist 和程序等待时间太长时闪退有关,经测试完全正常,删!
33 com.apple.appsupport.cplogd.plist -记录应用程序和第三方程序崩溃日志,删
34 com.apple.crash_mover.plist - 移动崩溃日志文件.删
*35 com.apple.mobile.softwareupdated.plist –删后,在 设置-通用-软件更新,那里失去检测固件升级的能力,考虑
36 com.apple.OTACrashCopier.plist - 把OTA崩溃日志移动到,删
37 com.apple.OTATaskingAgent.plist - 通知系统进行ota升级,不需要OTA自动更新的,删
38 com.apple.softwareupdateservicesd.plist - OTA升级服务,不需要OTA自动更新的,删.
39 com.apple.Springboard.SetupHelper.plist - IOS安装向导,只在刚刷完机或抹掉所有内容和设置时出现,越狱后抹除直接白苹果了,所以这个留着无用,删
40 com.apple.certui.relay.plist - 当你在一个公共网络,safari无法校验一个网站时,会提示这个网站未经过验证,是否继续,如果你不在乎,删
41 com.apple.sharktrace.plist 为开发者准备的崩溃日志,删
*42 com.apple.assitivetouchd.plist - 辅助功能里的assitivetouch,考虑
*45 com.apple.daily.plist –协助*35检查是否有固件更新,考虑
*47 com.apple.itunescloudd.plist - 关于itunes的云/家庭共享服务,考虑
*48 com.apple.midiserver-ios.plist- 删
*55 com.apple.twitterd.plist - 国外推特相关服务,没Vρ∩并且不用推特的可删除,考虑&
你可能喜欢的
人生就像一场没有目的地的旅行,过往只是沿途的一站iOS应用崩溃日志揭秘 - cy-app
- 博客频道 - CSDN.NET
15175人阅读
本文作者是&, 他是一名独立iOS开发者。
作为一名应用开发者,你是否有过如下经历?
为确保你的应用正确无误,在将其提交到应用商店之前,你必定进行了大量的测试工作。它在你的设备上也运行得很好,但是,上了应用商店后,还是有用户抱怨会闪退 !
如果你跟我一样是个完美主义者,你肯定想将应用做到尽善尽美。于是你打开代码准备修复闪退的问题……但是,从何处着手呢?
这时iOS崩溃日志派上用场了。在大多数情况下,你能从中了解到关于闪退的详尽、有用的信息。
通过本教程,你将学习到一些常见的崩溃日志案例,以及如何从开发设备和iTunes Connect上获取崩溃日志文件。你还将学习到符号化( symbolication),从日志追踪到代码 。你还将学习调试一个在待定情况下会闪退的应用。
让我们开始动手吧!
什么是崩溃日志,从哪里能得它?
iOS设备上的应用闪退时,操作系统会生成一个崩溃报告,也叫崩溃日志,保存在设备上。
崩溃日志上有很多有用的信息,包括应用是什么情况下闪退的。通常,上面有每个正在执行线程的完整堆栈跟踪信息,所以你能从中了解到闪退发生时各线程都在做什么,并分辨出闪退发生在哪个线程上。
有几种方法可以从设备上获取崩溃日志。
设备与电脑上的iTunes Store同步后,会将崩溃日志保存在电脑上。根据电脑操作系统的不同,崩溃日志将保存在以下位置:
~/Library/Logs/CrashReporter/MobileDevice/
Windows XP:
C:Documents and Settings&USERNAME&Application DataApple ComputerLogsCrashReporterMobileDevice&DEVICE_NAME&
Windows Vista or 7:
C:Users&USERNAME&AppDataRoamingApple ComputerLogsCrashReporterMobileDevice&DEVICE_NAME&
当用户抱怨闪退时,你可以要求他让设备与iTunes同步,并根据操作系统的不同,到上述位置把崩溃日志下载下来,然后通过电子邮件发送给你。
你必需尽量获取用户设备生成的所有崩溃日志。因为崩溃日志越多,就越容易诊断问题所在!
另外,如果你装了Xcode,也能很容易通过Xcode从你的设备上获得崩溃日志。将iOS设备连接到电脑上,然后打开Xcode。从菜单栏上选择 Window &菜单, 然后选择&Organizer (快捷方式是 Shift-CMD-2).
在 Organizer 窗口上, 选中&Devices 标签栏. 在左侧的导航面板上,选中&Device Logs, 如下图所示:
看看上图,左侧有好几个 Device Logs 菜单项. LIBRARY 下面的Device Logs是你所有设备(曾经连接到Xcode的)的日志 。每个设备下面的 Device Logs 是对应设备的日志。
应用提交到App Store后,你也能从&&获取到用户的崩溃日志. 登录到 iTunes Connect 上, 选择Manage Your Applications, 点击相应的应用, 点击应用图标下面的&View Details&按钮, 然后点击右栏Links部分的 &Crash Reports&。
如果没有崩溃日志,试试点击Refresh&按钮刷新一下。如果你的应用还卖得不多,或者刚上架不久,iTunes Connect账号上也可能还没有任何崩溃日志。
如果iTunes Connect上有崩溃日志,你将看到如下图:
有时,尽管有用户报告闪退,你仍然看不到崩溃报告。这时,最好让用户直接把崩溃报告发送给你。
什么情况下会产生崩溃日志?
两种主要情况会产生崩溃日志:
应用违反操作系统规则。应用中有Bug。
违反iOS规则包括在启动、恢复、挂起、退出时watchdog超时、用户强制退出和低内存终止。让我们详细了解一下吧。
Watchdog 超时机制
从iOS 4.x开始,退出应用时,应用不会立即终止,而是退到后台。
但是,如果你的应用响应不够快,操作系统有可能会终止你的应用,并产生一个崩溃日志。这些事件与下列UIApplicationDelegate方法相对应:
application:didFinishLaunchingWithOptions:applicationWillResignActive:applicationDidEnterBackground:applicationWillEnterForeground:applicationDidBecomeActive:applicationWillTerminate:
上面所有这些方法,应用只有有限的时间去完成处理。如果花费时间太长,操作系统将终止应用。
注意: 如果你没有把需要花费时间比较长的操作(如网络访问)放在后台线程上就很容易发生这种情况。关于如果避免这种情况的信息,请参考我们的另外两篇教程:&Grand Central Dispatch&和&NSOperations。
用户强制退出
iOS 4.x开始支持多任务。如果应用阻塞界面并停止响应, 用户可以通过在主屏幕上双击Home按钮来终止应用。此时,操作应用将生成一个崩溃日志。
注意:&双击Home按钮后,你将看到运行过的所有应用。那些应用不一定是正在运行,也不一定是被挂起。
通常,用户点击Home按钮时,应用将在后台保留约10分钟,然后操作系统自动将其终止。 所以双击Home按钮显示的应用列表只是表明那是一系列过去打开过的应用。删除那些应用的图标不会产生任何崩溃日志。
低内存终止
子类化UIViewController时,你或许已经注意到didReceiveMemoryWarning方法。
在前台运行的应用拥有访问和使用内存的最高优化级。然而,这并不意味着该应用能使用设备的所有可用内存 ——每个应用只能使用一部分可用内存。
当内存使用达到一定程度时,操作系统将发出一个&UIApplicationDidReceiveMemoryWarningNotification 通知。同时,调用&didReceiveMemoryWarning&方法。
此时,为了让应用继续正常运行,操作系统开始终止在后台的其他应用以释放一些内存。所有后台应用被终止后,如果你的应用还需要更多内存,操作系统会将你的应用也终止掉,并产生一个崩溃日志。而在这种情况下被终止的后台应用,不会产生崩溃日志。
注意:&根据&, Xcode不会自动添加低内存日志。你必需手动获取日志。 然而,根据我的个人经验,使用 Xcode 4.5.2, 低内存日志也会自动导入,只是”Process”和”Type”属性都被标为Unknown(未知)。
另外,&#20540;得一提的是在极短时间内分配一大块内存将给系统内存带来巨大负担。这样,也会产生内存警告的通知。
应用中有Bug
如你所想,大多数闪退都是由于应用中有Bug,因此大多数崩溃日志的产生都是因为应用中的Bug。Bug的种类的有很多。
在本教程的后半部分,你将通过调试一个会产生崩溃日志的含有Bug的应用,学习如何找到问题所在并进行修复!
崩溃日志的实例
让我们看看一个崩溃日志的实例,以使你在处理一些实际问题之前心里有谱。
事不宜迟,见见你的新朋友吧:
// 1: 进程信息
Incident Identifier: 30E46451-53FD-7FC11AD05F
CrashReporter Key:&& 5af867f6eec76afee451bf9ae5f31
Hardware Model:&&&&& iPhone4,1
Process:&&&&&&&& Rage Masters [4155]
Path:&&&&&&&&&&& /var/mobile/Applications/AEF-4CEB-94B6-FE158D885014/Rage Masters.app/Rage Masters
Identifier:&&&&& Rage Masters
Version:&&&&&&&& ??? (???)
Code Type:&&&&&& ARM (Native)
Parent Process:& launchd [1]
// 2: 基本信息
Date/Time:&&&&&&
21:39:06.967 -0400
OS Version:&&&&& iOS 6.0 (10A403)
Report Version:& 104
// 3: 异常
Exception Type:&
Exception Codes: 0xbadf00d
Highlighted Thread:& 0
// 4: 线程回溯
Thread 0 name:& Dispatch queue: com.apple.main-thread
0&& libsystem_kernel.dylib&&&&&& &&& &0x327f2eb4 mach_msg_trap &#43; 20
1&& libsystem_kernel.dylib&&&&&& &&& &0x327f3048 mach_msg &#43; 36
2&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd4040 __CFRunLoopServiceMachPort &#43; 124
3&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd2d9e __CFRunLoopRun &#43; 878
4&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45eb8 CFRunLoopRunSpecific &#43; 352
5&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45d44 CFRunLoopRunInMode &#43; 100
6&& CFNetwork&&&&&&&&&&&&&&&&&&& &&& &0x32ac343e CFURLConnectionSendSynchronousRequest &#43; 330
7&& Foundation&&&&&&&&&&&&&&&&&& &&& &0x346e69ba &#43;[NSURLConnection sendSynchronousRequest:returningResponse:error:] &#43; 242
8&& Rage Masters&&&&&&&&&&&&&&&& &&& &0x000d00 &#43; 8262
0&& libsystem_kernel.dylib&&&&&& &&& &0x32803d98 __workq_kernreturn &#43; 8
1&& libsystem_c.dylib&&&&&&&&&&& &&& &0x3a987cf6 _pthread_workq_return &#43; 14
2&& libsystem_c.dylib&&&&&&&&&&& &&& &0x3a987a12 _pthread_wqthread &#43; 362
3&& libsystem_c.dylib&&&&&&&&&&& &&& &0x3a9878a0 start_wqthread &#43; 4
// 5: 线程状态
Thread 0 crashed with ARM Thread State (32-bit):
&&& r0: 0x&&& r1: 0x&&&&& r2: 0x&&&&& r3: 0x39529fc8
&&& r4: 0xffffffff&&& r5: 0x2fd7d301&&&&& r6: 0x2fd7d300&&&&& r7: 0x2fd7d9d0
&&& r8: 0x2fd7d330&&& r9: 0x3adbf8a8&&&& r10: 0x2fd7d308&&&& r11: 0x
&&& ip: 0x&&& sp: 0x2fd7d2ec&&&&& lr: 0x001bdb25&&&&& pc: 0x
& cpsr: 0x
// 6: 二进制映像
Binary Images:
0xd2000 -&&& 0xd7fff &#43;Rage Masters armv7&& /var/mobile/Applications/AEF-4CEB-94B6-FE158D885014/Rage Masters.app/Rage Masters
0x2fe41000 - 0x2fe61fff& dyld armv7&& /usr/lib/dyld
0x327f2000 - 0x32808fff& libsystem_kernel.dylib armv7&& /usr/lib/system/libsystem_kernel.dylib
0x328a8000 - 0x328bdfff& libresolv.9.dylib armv7&& /usr/lib/libresolv.9.dylib
0x32a70000 - 0x32b35fff& CFNetwork armv7&& /System/Library/Frameworks/CFNetwork.framework/CFNetwork
0x32b7a000 - 0x32cc3fff& libicucore.A.dylib armv7&& /usr/lib/libicucore.A.dylib
0x32cc4000 - 0x32cc5fff& CoreSurface armv7&& /System/Library/PrivateFrameworks/CoreSurface.framework/CoreSurface
0x32f65000 - 0x32f8afff& OpenCL armv7&& /System/Library/PrivateFrameworks/OpenCL.framework/OpenCL
这报告看起来像天书。:) 我们分几部分来解读吧:
(1) 进程信息
第一部分是闪退进程的相关信息。
Incident Identifier是崩溃报告的唯一标识符。CrashReporter Key&是与设备标识相对应的唯一键&#20540;。虽然它不是真正的设备标识符,但也是一个非常有用的情报:如果你看到100个崩溃日志的CrashReporter Key&#20540;都是相同的,或者只有少数几个不同的CrashReport&#20540;,说明这不是一个普遍的问题,只发生在一个或少数几个设备上。Hardware Model&标识设备类型。 如果很多崩溃日志都是来自相同的设备类型,说明应用只在某特定类型的设备上有问题。上面的日志里,崩溃日志产生的设备是iPhone 4s。Process&是应用名称。中括号里面的数字是闪退时应用的进程ID。接下来几行不言自明,无需赘述。
(2) 基本信息
这部分给出了一些基本信息,包括闪退发生的日期和时间,设备的iOS版本。如果有很多崩溃日志都来自iOS 6.0,说明问题只发生在iOS 6.0上。
在这部分,你可以看到闪退发生时抛出的异常类型。还能看到异常编码和抛出异常的线程。根据崩溃报告类型的不同,在这部分你还能看到一些另外的信息。
(4) 线程回溯
这部分提供应用中所有线程的回溯日志。&回溯是闪退发生时所有活动帧清单。它包含闪退发生时调用函数的清单。看下面这行日志:
2&&& XYZLib&&& 0x34648e88&&& 0x83000 &#43; 8740
它包括四列:
帧编号—— 此处是2。二进制库的名称 ——此处是 XYZLib.调用方法的地址 ——此处是 0x34648e88.第四列分为两个子列,一个基本地址和一个偏移量。此处是0×83000 &#43; 8740, 第一个数字指向文件,第二个数字指向文件中的代码行。
(5) 线程状态
这部分是闪退时寄存器中的&#20540;。一般不需要这部分的信息,因为回溯部分的信息已经足够让你找出问题所在。
(6) 二进制映像
这部分列出了闪退时已经加载的二进制文件。
符号化Symbolication
第一次看到崩溃日志上的回溯时,你或许会觉得它没什么意义。我们习惯使用方法名和行数,而非像这样的神秘位置:
6&&& Rage Masters&&& 0x0001625c&&& 0x2a000 &#43; 3003
将这些十六进制地址转化成方法名称和行数的过程称之为符号化。
从Xcode的Organizer窗口获取崩溃日志后过几秒钟,崩溃日志将被自动符号化。上面那行被符号化后的版本如下 :
6&&& Rage Masters&&& 0x0001625c&&& -[RMAppDelegate application:didFinishLaunchingWithOptions:] (RMAppDelegate.m:35)
Xcode符号化崩溃日志时,需要访问与App Store上对应的应用二进制文件以及生成二进制文件时产生的&.dSYM 文件。必需完全匹配才行。否则,日志将无法被完全符号化。
所以,保留每个分发给用户的编译版本非常重要。提交应用前进行归档时,Xcode将保存应用的二进制文件。可以在Xcode Organizer的Archives标签栏下找到所有已归档的应用文件。
在发现崩溃日志时,如果有相匹配的.dSYM文件和应用二进制文件,Xcode会自动对崩溃日志进行符号化。如果你换到别的电脑或创建新的账户,务必将所有二进制文件移动到正确的位置,使Xcode能找到它们。
注意:&你必需同时保留应用二进制文件和.dSYM文件才能将崩溃日志完整符号化。每次提交到iTunes Connect的构建都必需归档。
.dSYM文件和二进制文件是特定绑定于每一次构建和后续构建的,即使来自相同的源代码文件,每一次构建也与其他构建不同,不能相互替换。
如果你使用Build 和 Archive 命令,这些文件会自动放在适当位置。 如果不是使用Build 和 Archive命令,放在Spotlight能够搜索到的位置(比如Home目录)即可。
低内存闪退
因为低内存崩溃日志与普通崩溃日志略有不同,所以本教程特别分开说明一下。:]
iOS设备检测到低内存时,虚拟内存系统发出通知请求应用释放内存。这些通知发送到所有正在运行的应用和进程,试图收回一些内存。
如果内存使用依然居高不下,系统将会终止后台线程以缓解内存压力。如果可用内存足够,应用将能够继续运行而不会产生崩溃报告。否则,应用将被iOS终止,并产生低内存崩溃报告。
低内存崩溃日志上没有应用线程的堆栈回溯。相反,上面显示的是以内存页数为单位的各进程内存使用量。(在撰写本文的时候,一个内存页的大小是4KB。)
被iOS因释放内存页终止的进程名称后面你会看到jettisoned 字样。如果看到它出现在你的应用名称后面,说明你的应用因使用太多内存而被终止了。
低内存崩溃日志看起来像这样:
Incident Identifier: 30E46451-53FD-7FC11AD05F
CrashReporter Key:&& 5af867f6eec76afee451bf9ae5f31
OS Version:&&&&&&&&& iPhone OS 3.1.3 (7E18)
Date/Time:&&&&&&&&&&
21:39:06.967 -0400
Free pages:&&&&&&& 96
Wired pages:&&&&&& 10558
Purgeable pages:&& 0
Largest process:&& Rage Masters
&&&&&&&& Name&&&&&&&&&&&&&&&& UUID&&&&&&&&&&&&&&&&&&& Count resident pages
&&& Rage Masters&&&& 9320 (jettisoned) (active)
&&& mediaserverd&&&&& 255
&&&& dataaccessd&&&&& 505
&&&&&&&& syslogd&&&&&& 71
&&&&&&&&&&& apsd&&&&& 171
&&&&&& securityd&&&&& 243
&&&&&&&& notifyd&&&& 2027
&&&&& CommCenter&&&&& 189
&&&& SpringBoard&&&& 2158 (active)
&&&&& accessoryd&&&&&& 91
&&&&&&&& configd&&&&& 371
&&&&&& fairplayd&&&&&& 93
&& mDNSResponder&&&&& 292
&&&&&& lockdownd&&&& 1204
&&&&&&&& launchd&&&&&& 72
当应用发生低内存闪退时,你必需看看应用中内存使用的方式,以及是如何处理低内存警告的。你可以使用Instruments工具中使用Allocations 和 Leaks来发现内存分配问题和内存泄漏问题。如果你不知道如何利用 Instruments 检查内存问题,可以看看&。
还有,别忘记虚拟内存! Instruments工具的Leaks 和 Allocations 不能跟踪显存使用情况。必需使用 VM Tracker 才能查看显存使用情况。
VM Tracker 默认是关闭的。打开Instrument,手动 选中Automatic Snapshotting 标志或者按下Snapshot Now 按钮。
本教程后面将会学习如何研究低内存崩溃日志。
在研究真实闪退场景之前,还有一点需要重点介绍一下:就是那些有趣的异常编码 。
你可以在报告的异常部分——前面代码的第3部分找到异常编码。有些编码比较常见。
通常,异常编码以一些文字开头,紧接着是一个或多个十六进制&#20540;,此数&#20540;正是说明闪退根本性质的所在。 &从这些编码中,可以区分出闪退是因为程序错误、非法内存访问或者是其他原因。
下面是一些常见的异常编码:
0x8badf00d: 读做 “ate bad food”! (把数字换成字母,是不是很像 :p)该编码表示应用是因为发生watchdog超时而被iOS终止的。 &通常是应用花费太多时间而无法启动、终止或响应用系统事件。
0xbad22222: 该编码表示 VoIP 应用因为过于频繁重启而被终止。0xdead10cc: 读做 “dead lock”!该代码表明应用因为在后台运行时占用系统资源,如通讯录数据库不释放而被终止 。0xdeadfa11: 读做 “dead fall”! 该代码表示应用是被用户强制退出的。根据苹果文档, 强制退出发生在用户长按开关按钮直到出现 “滑动来关机”, 然后长按 Home按钮。强制退出将产生 包含0xdeadfa11 异常编码的崩溃日志, 因为大多数是强制退出是因为应用阻塞了界面。
注意: 在后台任务列表中关闭已挂起的应用不会产生崩溃日志。 一旦应用被挂起,它何时被终止都是合理的。所以不会产生崩溃日志。
大展身手的时候到了!
好了! 你已经学习了所有分析崩溃日志和修复错误的基础知识!
假设你刚进入Rage-O-Rage有限公司工作。该公司有一个在App Store上热销的应用,叫 Rage Masters。
你的老板安迪要你帮忙解决几个用户经常抱怨闪退问题。你的任务就是研究这些闪退,符号化用户提供的崩溃日志,查找问题所在,并修复之。
你可以从&下载应用的源代码。
注意: 如果你想自己重新生成崩溃报告,请遵照以下指引:
下载源码然后在Xcode中打开工程文件。使用正确的provisioning profile连接到iOS设备。从Xcode工具栏上选择iOS设备——不是模拟器作为target,然后构建应用。当你在设备上到默认页面(应用的全屏图片)时,立即在Xcode上点击停止按钮。关闭 Xcode。在设备上直接打开应用。测试场景,完成后连接设备到电脑上,通过Xcode获取崩溃日志。
场景 1: 糟糕的代码
一封来自用户的邮件: “大哥,你的应用就是一坨屎! 我将其下载到我自己的iPod Touch和iPhone上,还下载到我儿子的iPod Touch上。在所有的设备上,都是还没打开就闪退了……”
别一封来自用户的邮件说, “我下载了你们的应用,一打开就闪退。真悲催…”
另一封邮件说得更明确:”你们的应用不能运行。我把它下载到我和妻子的设备上。所有设备都是 一打开就闪退了…”
好吧,别灰心! 这些意见藏着什么玄机呢?让我们看看崩溃日志吧:
Incident Identifier: 85833DBA-3DF7-43EE-AF80-4E5C51091F42
CrashReporter Key:&& 5af867f6eec76afee451bf9ae5f31
Hardware Model:&&&&& iPhone4,1
Process:&&&&&&&& Rage Masters [20067]
Path:&&&&&&&&&&& /var/mobile/Applications/BD1F-4E61-BB18-0F/Rage Masters.app/Rage Masters
Identifier:&&&&& Rage Masters
Version:&&&&&&&& ??? (???)
Code Type:&&&&&& ARM (Native)
Parent Process:& launchd [1]
Date/Time:&&&&&&
13:37:31.148 -0400
OS Version:&&&&& iOS 6.0 (10A403)
Report Version:& 104
Exception Type:&
Exception Codes: 0xbadf00d
Highlighted Thread:& 0
Application Specific Information:
Soheil-Azarpour.Rage-Masters failed to launch in time
Elapsed total CPU time (seconds): 8.030 (user 8.030, system 0.000), 20% CPU
Elapsed application CPU time (seconds): 3.840, 10% CPU
Thread 0 name:& Dispatch queue: com.apple.main-thread
0&& libsystem_kernel.dylib&&&&&& &&& &0x327f2eb4 mach_msg_trap &#43; 20
1&& libsystem_kernel.dylib&&&&&& &&& &0x327f3048 mach_msg &#43; 36
2&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd4040 __CFRunLoopServiceMachPort &#43; 124
3&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd2d9e __CFRunLoopRun &#43; 878
4&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45eb8 CFRunLoopRunSpecific &#43; 352
5&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45d44 CFRunLoopRunInMode &#43; 100
6&& CFNetwork&&&&&&&&&&&&&&&&&&& &&& &0x32ac343e CFURLConnectionSendSynchronousRequest &#43; 330
7&& Foundation&&&&&&&&&&&&&&&&&& &&& &0x346e69ba &#43;[NSURLConnection sendSynchronousRequest:returningResponse:error:] &#43; 242
8&& Rage Masters&&&&&&&&&&&&&&&& &&& &0x000ea1c4 -[RMAppDelegate application:didFinishLaunchingWithOptions:] (RMAppDelegate.m:36)
9&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f30ad4 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] &#43; 248
10& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f3065e -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] &#43; 1186
11& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f28846 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] &#43; 694
12& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ed0c3c -[UIApplication handleEvent:withNewEvent:] &#43; 1000
13& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ed06d0 -[UIApplication sendEvent:] &#43; 68
14& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ed011e _UIApplicationHandleEvent &#43; 6150
15& GraphicsServices&&&&&&&&&&&& &&& &0x _PurpleEventCallback &#43; 588
16& GraphicsServices&&&&&&&&&&&& &&& &0x370831ce PurpleEventCallback &#43; 30
17& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd4170 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ &#43; 32
18& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd4112 __CFRunLoopDoSource1 &#43; 134
19& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd2f94 __CFRunLoopRun &#43; 1380
20& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45eb8 CFRunLoopRunSpecific &#43; 352
21& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45d44 CFRunLoopRunInMode &#43; 100
22& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f27480 -[UIApplication _run] &#43; 664
23& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f242fc UIApplicationMain &#43; 1116
24& Rage Masters&&&&&&&&&&&&&&&& &&& &0x000ea004 main (main.m:16)
25& libdyld.dylib&&&&&&&&&&&&&&& &&& &0x3b630b1c start &#43; 0
发现问题了吗? 异常编码是0xbadf00d,还有后面的报告:
Application Specific Information:
Soheil-Azarpour.Rage-Masters failed to launch in time
Elapsed total CPU time (seconds): 8.030 (user 8.030, system 0.000), 20% CPU
Elapsed application CPU time (seconds): 3.840, 10% CPU
这说明应用在启动时就闪退了,iOS的watchdog机制终止了应用。帅! 找到问题了,但是为什会发生这样的事呢?
接着往下看日志。 从下向上读回溯日志。最底下的帧 (frame 25: libdyld.dylib)是最先调用的,然后是帧24, Rage Masters, main (main.m:16) ,依此类推。
跟应用源代码相关的帧是最重要的。忽略掉系统库和框架。下一个与代码相关的帧是:
8&&& Rage Masters&&& 0x -[RMAppDelegate application:didFinishLaunchingWithOptions:] (RMAppDelegate.m:35)
应用在执行RMAppDelegate (RMAppDelegate.m:35)类application:didFinishLaunchingWithOptions:&方法第35 行代码时闪退。打开Xcode看看那行代码:
NSData *directoryData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
就是它了! 同步调用web服务?! 在主线程上?! 在 application:didFinishLaunchingWithOptions: 方法上?!! 谁写的代码呀?!
Network calls on the main thread makes kittens sad.
不管如何,问题得你来修复了。这个调用必需异步进行,甚至更理想的情况是,在application:didFinishLaunchingWithOptions:返回YES之后的其他部分再执行Web服务。
在其他地方调用可能需要比较多的修改。当下,我们只要使应用不闪退就行。可以在日后再实现更好的设计。 将上面那行讨厌的代码(及其下面的三行代码)换成下面这个异步的版本吧:
&[NSURLConnection sendAsynchronousRequest:request
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& queue:[NSOperationQueue mainQueue]
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
&&&&&&&& {
&&&&&&&&&&&& NSURL *cacheDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSUserDirectory inDomains:NSCachesDirectory] lastObject];
&&&&&&&&&&&& NSURL *filePath = [NSURL URLWithString:kDirectoryFile relativeToURL:cacheDirectory];
&&&&&&&&&&&& [data writeToFile:[filePath absoluteString] atomically:YES];
&&&&&&&& }];
场景 2: 无法响应事件的按钮
一名用户说: “我不能将某个rage master添加到书签里面。我想添加的时候应用就闪退…”
用一名用户说 :”书签不能用 … 在详细页面上,点击书签按钮,应用就闪退了!”
上面的抱怨说得不是很清楚,引起问题的原因肯定有多样。看看崩溃日志:
Incident Identifier: 3AAA63CC-3088-41CC-84D9-82FE03F9F354
CrashReporter Key:&& 5af867f6eec76afee451bf9ae5f31
Hardware Model:&&&&& iPhone4,1
Process:&&&&&&&& Rage Masters [20090]
Path:&&&&&&&&&&& /var/mobile/Applications/BD1F-4E61-BB18-0F/Rage Masters.app/Rage Masters
Identifier:&&&&& Rage Masters
Version:&&&&&&&& ??? (???)
Code Type:&&&&&& ARM (Native)
Parent Process:& launchd [1]
Date/Time:&&&&&&
13:39:00.081 -0400
OS Version:&&&&& iOS 6.0 (10A403)
Report Version:& 104
Exception Type:& EXC_CRASH (SIGABRT)
Exception Codes: 0x0
Crashed Thread:& 0
Last Exception Backtrace:
0&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bff29e __exceptionPreprocess &#43; 158
1&& libobjc.A.dylib&&&&&&&&&&&&& &&& &0x34f0f97a objc_exception_throw &#43; 26
2&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36c02e02 -[NSObject(NSObject) doesNotRecognizeSelector:] &#43; 166
3&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36c0152c ___forwarding___ &#43; 388
4&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b58f64 _CF_forwarding_prep_0 &#43; 20
5&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb0a8 -[UIApplication sendAction:to:from:forEvent:] &#43; 68
6&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb05a -[UIApplication sendAction:toTarget:fromSender:forEvent:] &#43; 26
7&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb038 -[UIControl sendAction:to:forEvent:] &#43; 40
8&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fba8ee -[UIControl(Internal) _sendActionsForEvents:withEvent:] &#43; 498
9&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbade4 -[UIControl touchesEnded:withEvent:] &#43; 484
10& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ee35f4 -[UIWindow _sendTouchesForEvent:] &#43; 520
11& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ed0804 -[UIApplication sendEvent:] &#43; 376
12& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ed011e _UIApplicationHandleEvent &#43; 6150
13& GraphicsServices&&&&&&&&&&&& &&& &0x3708359e _PurpleEventCallback &#43; 586
14& GraphicsServices&&&&&&&&&&&& &&& &0x370831ce PurpleEventCallback &#43; 30
15& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd416e __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ &#43; 30
16& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd4112 __CFRunLoopDoSource1 &#43; 134
17& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd2f94 __CFRunLoopRun &#43; 1380
18& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45eb8 CFRunLoopRunSpecific &#43; 352
19& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45d44 CFRunLoopRunInMode &#43; 100
20& GraphicsServices&&&&&&&&&&&& &&& &0x GSEventRunModal &#43; 70
21& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f242fc UIApplicationMain &#43; 1116
22& Rage Masters&&&&&&&&&&&&&&&& &&& &0x000ca004 main (main.m:16)
23& libdyld.dylib&&&&&&&&&&&&&&& &&& &0x3b630b1c start &#43; 0
异常代码是SIGABRT。通常, &SIGABRT 异常是由于某个对象接收到未实现的消息引起的。 或者,用简单的话说,在某个对象上调用了不存在的方法。
这种情况一般不会发生,因为A对象调用了B方法,如果B方法不存在,编译器会报错。但是,如果你是使用selector间接调用方法的,编译器则无法检测对象是否存在该方法了。
回到崩溃日志。它指出闪退发生在编号为0的线程上。 这意味着很可能是在主线程上调用了某个对象没有实现的方法。
如果你接着阅读回溯日志,会发现跟你的代码相关的只有帧22, main.m:16. 这没有多大帮助。 :[
继续向上查看框架调用,出现这个:
2&&& CoreFoundation&&& 0x36c02e02 -[NSObject(NSObject) doesNotRecognizeSelector:] &#43; 166
这不是你自己写的代码。但至少它确认了是对象调用了一个没有实现的方法。
回到RMDetailViewController.m文件, 因为那是书签按钮实现动作的地方。 找到书签功能代码:
-(IBAction)bookmarkButtonPressed {
&&& self.master.isBookmarked = !self.master.isB
&&& // Update shared bookmarks
&&& if (self.master.isBookmarked)
&&&&&&& [[RMBookmarks sharedBookmarks] bookmarkMaster:self.master];
&&&&&&& [[RMBookmarks sharedBookmarks] unbookmarkMaster:self.master];
&&& // Update UI
&&& [self updateBookmarkImage];
看起来没什么问题,再检查一下storyboard (XIB文件) ,确认按钮连接的正确性。
就是它了! 在 MainStoryboard.storyboard,按钮连接的是 bookmarkButtonPressed: 而不是bookmarkButtonPressed (注意后面的分号说明方法有一个参数)。 只要将上面的方法签名修改成这样就能修复问题了:
-(IBAction)bookmarkButtonPressed:(id)sender {
&&& // Remain unchanged..
当然,你也可以简单地在XIB文件上删除错误的连接,然后重新连接方法,使XIB文件连接到正确的方法上。两者方法都行。
又处理了一个闪退问题,好样的。:]
场景 3: 表&#26684;上的Bug
另一用户抱怨道, “在书签视图上无法删除书签…” 还有另一用户抱怨同样的问题, “当我试图删除书签时,应用闪退…”
这些邮件没什么作用,还是看看崩溃日志!
Incident Identifier: 5B62D681-D8FE-41FE-8D52-AB7E6D6B2AC7
CrashReporter Key:&& 5af867f6eec76afee451bf9ae5f31
Hardware Model:&&&&& iPhone4,1
Process:&&&&&&&& Rage Masters [20088]
Path:&&&&&&&&&&& /var/mobile/Applications/BD1F-4E61-BB18-0F/Rage Masters.app/Rage Masters
Identifier:&&&&& Rage Masters
Version:&&&&&&&& ??? (???)
Code Type:&&&&&& ARM (Native)
Parent Process:& launchd [1]
Date/Time:&&&&&&
13:38:45.762 -0400
OS Version:&&&&& iOS 6.0 (10A403)
Report Version:& 104
Exception Type:& EXC_CRASH (SIGABRT)
Exception Codes: 0x0
Crashed Thread:& 0
Last Exception Backtrace:
0&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bff29e __exceptionPreprocess &#43; 158
1&& libobjc.A.dylib&&&&&&&&&&&&& &&& &0x34f0f97a objc_exception_throw &#43; 26
2&& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bff158 &#43;[NSException raise:format:arguments:] &#43; 96
3&& Foundation&&&&&&&&&&&&&&&&&& &&& &0x346812aa -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] &#43; 86
4&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f04b7e -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] &#43; 7690
5&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] &#43; 22
6&& Rage Masters&&&&&&&&&&&&&&&& &&& &0x000fd9ca -[RMBookmarksViewController tableView:commitEditingStyle:forRowAtIndexPath:] (RMBookmarksViewController.m:68)
7&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] &#43; 80
8&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb0a8 -[UIApplication sendAction:to:from:forEvent:] &#43; 68
9&& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb05a -[UIApplication sendAction:toTarget:fromSender:forEvent:] &#43; 26
10& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb038 -[UIControl sendAction:to:forEvent:] &#43; 40
11& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fba8ee -[UIControl(Internal) _sendActionsForEvents:withEvent:] &#43; 498
12& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb0a8 -[UIApplication sendAction:to:from:forEvent:] &#43; 68
13& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb05a -[UIApplication sendAction:toTarget:fromSender:forEvent:] &#43; 26
14& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbb038 -[UIControl sendAction:to:forEvent:] &#43; 40
15& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fba8ee -[UIControl(Internal) _sendActionsForEvents:withEvent:] &#43; 498
16& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37fbade4 -[UIControl touchesEnded:withEvent:] &#43; 484
17& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ee35f4 -[UIWindow _sendTouchesForEvent:] &#43; 520
18& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ed0804 -[UIApplication sendEvent:] &#43; 376
19& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37ed011e _UIApplicationHandleEvent &#43; 6150
20& GraphicsServices&&&&&&&&&&&& &&& &0x3708359e _PurpleEventCallback &#43; 586
21& GraphicsServices&&&&&&&&&&&& &&& &0x370831ce PurpleEventCallback &#43; 30
22& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd416e __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ &#43; 30
23& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd4112 __CFRunLoopDoSource1 &#43; 134
24& CoreFoundation&&&&&&&&&&&&&& &&& &0x36bd2f94 __CFRunLoopRun &#43; 1380
25& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45eb8 CFRunLoopRunSpecific &#43; 352
26& CoreFoundation&&&&&&&&&&&&&& &&& &0x36b45d44 CFRunLoopRunInMode &#43; 100
27& GraphicsServices&&&&&&&&&&&& &&& &0x GSEventRunModal &#43; 70
28& UIKit&&&&&&&&&&&&&&&&&&&&&&& &&& &0x37f242fc UIApplicationMain &#43; 1116
29& Rage Masters&&&&&&&&&&&&&&&& &&& &0x000fb004 main (main.m:16)
30& libdyld.dylib&&&&&&&&&&&&&&& &&& &0x3b630b1c start &#43; 0
这看起来跟前面那个崩溃日志很像。是另一个SIGABRT 异常。 你可能想知道是否是相同的问题:发送信息到一个没有实现相应方法的对象?
让我们从回溯日志看看哪些方法被调用了。从底部开始,你的源代码最后被调用的是帧 6:
6&&& Rage Masters&&& 0x00088c66 -[RMBookmarksViewController tableView:commitEditingStyle:forRowAtIndexPath:] (RMBookmarksViewController.m:68)
这是UITableViewDataSource 的一个方法. 呵呵?! 毫无疑问苹果已经实现了该方法 —— 你可以重载它, 但不像是还没有实现。而且,这是个可选的委派方法。 所以问题不是调用了一个没有实现的方法。
再看看上面的几个帧:
3&&& Foundation&&& 0x346812aa -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] &#43; 86
4&&& UIKit&&&&&&&& 0x37f04b7e -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] &#43; 7690
5&&& UIKit&&&&&&&& 0x -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] &#43; 22
帧 5, UITableView调用了它自己的另一个方法&deleteRowsAtIndexPaths:withRowAnimation:&然后是看起来像苹果内部方法的_endCellAnimationsWithContext: 被调用。然后Foundation framework发生异常handleFailureInMethod:object:file:lineNumber:description:.
这些分析结合用户的抱怨,看起来是你在处理UITableView删除行过程中有Bug。回到Xcode。你知道看哪里吗 ? 能从崩溃日志中判断出来? 就是RMBookmarksViewController.m文件的第68行:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
&&& [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
发现问题了吗? 给你点时间,仔细看一下。
找到了吧! 数据源呢? 代码在表&#26684;视图上删除了一行,但并没有修改背后的数据源。把上面的代码替换成下面的就能修复问题了:
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
&&& RMMaster *masterToDelete = [bookmarks objectAtIndex:indexPath.row];
&&& [bookmarks removeObject:masterToDelete];
&&& [[RMBookmarks sharedBookmarks] unbookmarkMaster:masterToDelete];
&&& [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
搞定了!走起,讨厌的 bug!!
场景 4: 吃棒棒糖时闪退!
用户邮件说, “当rage master吃棒棒糖时应用就闪退…” 另一用户说, “我让rage master 吃棒棒糖,没几次应用就闪退了!”
崩溃日志如下:
Incident Identifier: 081E58F5-95A8-404D-947B-5E104B6BC1B1
CrashReporter Key:&& 5af867f6eec76afee451bf9ae5f31
Hardware Model:&&&&& iPhone4,1
OS Version:&&&&&&&&& iPhone OS 6.0 (10A403)
Kernel Version:&&&&& Darwin Kernel Version 13.0.0: Sun Aug 19 00:28:05 PDT 2012; root:xnu-~4/RELEASE_ARM_S5L8940X
Date:&&&&&&&&&&&&&&&
13:39:59 -0400
Time since snapshot: 4353 ms
Free pages:&&&&&&& 968
Active pages:&&&&& 7778
Inactive pages:&&& 4005
Throttled pages:&& 92319
Purgeable pages:&& 0
Wired pages:&&&&&& 23347
Largest process:&& Rage Masters
&&&& Name&&&&&&&&&&&&&&&&&&& &UUID&&&&&&&&&&&&&&&&&&&&&&& rpages&&&&&& recent_max&&&&&& [reason]&&&&&&&&& (state)
&&&&&&&&&&&& lsd &6a9f5b5f36b23fc78f87b6d8f1f49a9d&&&&&&&&&& 331&&&&&&&&&&&&& 331&&&&&&&& [vm]&&&&&&&& (daemon) (idle)
&&&&&&&&&&& afcd &b0aff2e2fec81a8dcdbb2&&&&&&&&&& 141&&&&&&&&&&&&& 141&&&&&&&& [vm]&&&&&&&& (daemon) (idle)
&&& itunesstored &4e0cd9f873deb2d6d13d&&&&&&&&& 1761&&&&&&&&&&&& 1761&&&&&&&& [vm]&&&&&&&& (daemon) (idle)
softwareupdatese &2bc4b5aed3b34f81027d0ae&&&&&&&&&& 311&&&&&&&&&&&&& 311&&&&&&&& [vm]&&&&&&&& (daemon) (idle)
&&&&&&&&& Amazon &ec3e59af67ba14&&&&&&&&& 2951&&&&&&&&&&&& 2951&&&&&&&& [vm]&&&&&&&& (suspended)
&&&&&& accountsd &ac0fce15c1aefc498d521ac7&&&&&&&&&& 519&&&&&&&&&&&&& 519&&&&&&&& [vm]&&&&&&&& (daemon) (idle)
coresymbolicatio &edbab153b4b&&&&&&&&&& 126&&&&&&&&&&&&& 126&&&&&&&& [vm]&&&&&&&& (daemon) (idle)
&&&&&&&&&& Skype &504cf2fe60cb3cdea836b&&&&&&&&& 3187&&&&&&&&&&&& 3187&&&&&&&& [vm]&&&&&&&& (background)
&&&&& MobileMail &bff817c61ce33c85a43ea9a6c98c29f5&&&&&&&& 14927&&&&&&&&&&& 14927&&&&&&&& [vm]&&&&&&&& (continuous)
&&&&&& MobileSMS &4d67aeea207464cfc581&&&&&&&&& 2134&&&&&&&&&&&& 2134&&&&&&&& [vm]&&&&&&&& (background)
&&&& MobilePhone &3fca241f2a193d0fbea41&&&&&&&&& 2689&&&&&&&&&&&& 2689&&&&&&&& [vm]&&&&&&&& (continuous)
&&&&& librariand &c9a9be81aace79b911f27e&&&&&&&&&& 317&&&&&&&&&&&&& 317&&&&&&&& [vm]&&&&&&&& (daemon)
&&&&&&&&&&&& kbd &3e7136ddcefc3d77a0cd&&&&&&&&&& 616&&&&&&&&&&&&& 616&&&&&&&& [vm]&&&&&&&& (daemon)
&&&&&&&&&&& tccd &eb5ddcfd987d67cae6a4c4ea&&&&&&&&&& 224&&&&&&&&&&&&& 224&&&&&&&& [vm]&&&&&&&& (daemon)
&&& Rage Masters &90b45dc5b06cf7dc4d492&&&&&&&& 28591&&&&&&&&&&& 28591&&&&&&&& [vm]&&&&&&&& (frontmost) (resume)
&&&&&&&&&&& ptpd &04a56fce9aeea8e5a7ea&&&&&&&&&& 879&&&&&&&&&&&&& 879&&&&&&&&&&&&&&&&&&&&& (daemon)
&& iaptransportd &f784f30dc09de8113ef6&&&&&&&&&& 230&&&&&&&&&&&&& 230&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&& locationd &892cd1c9ffa43c99a82dba197be5f09e&&&&&&&&& 1641&&&&&&&&&&&& 1641&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&& syslogd &cbef142fa0a839f0885afb693fb169c3&&&&&&&&&& 237&&&&&&&&&&&&& 237&&&&&&&&&&&&&&&&&&&&& (daemon)
&&& mediaserverd &daca32c9b8f3a6b1faac43a2&&&&&&&&& 4869&&&&&&&&&&&& 4869&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&& dataaccessd &2a3f6a518f3f3646bf35eddd36f25005&&&&&&&&& 1786&&&&&&&&&&&& 1786&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&& aosnotifyd &d4d14fe447cfef3e6542&&&&&&&&&& 549&&&&&&&&&&&&& 549&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&&&& wifid &37998cdbb9b34f090d0c&&&&&&&&&& 455&&&&&&&&&&&&& 455&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&& SpringBoard &27372aae101f3bbc87804edc10314af3&&&&&&&& 18749&&&&&&&&&&& 18749&&&&&&&&&&&&&&&&&&& &
&&&&& backboardd &b33eda98eb5c72c098858&&&&&&&&& 5801&&&&&&&&&&&& 5801&&&&&&&&&&&&&&&&&&&&& (daemon)
& UserEventAgent &6edfd8d8dbadcdfc94f90&&&&&&&&&& 601&&&&&&&&&&&&& 601&&&&&&&&&&&&&&&&&&&&& (daemon)
&&& mediaremoted &4ff39c50c6ace813cb25&&&&&&&&&& 293&&&&&&&&&&&&& 293&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&& pasteboardd &8aa321f84a076a711dc1c51&&&&&&&&&& 176&&&&&&&&&&&&& 176&&&&&&&&&&&&&&&&&&&&& (daemon)
springboardservi &ff6f64b3a21a39c9a1793321eefa5304&&&&&&&&&&&& 0&&&&&&&&&&&&&&& 0&&&&&&&&&&&&&&&&&&&&& (daemon)
&&& syslog_relay &45eabb54426&&&&&&&&&&&& 0&&&&&&&&&&&&&&& 0&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&& DTMobileIS &2aaa9047854ea&&&&&&&&&&&& 0&&&&&&&&&&&&&&& 0&&&&&&&&&&&&&&&&&&&&& (daemon)
notification_pro &845b7beebc8538ca9ceef&&&&&&&&&& 169&&&&&&&&&&&&& 169&&&&&&&&&&&&&&&&&&&&& (daemon)
&&& syslog_relay &45eabb54426&&&&&&&&&&&& 0&&&&&&&&&&&&&&& 0&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&&&&&& ubd &74dc476dfcda555fcb8d774&&&&&&&&&& 976&&&&&&&&&&&&& 976&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&& twitterd &4bc397d55b8e&&&&&&&&&& 730&&&&&&&&&&&&& 730&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&& configd &ecf6b8671844&&&&&&&&&& 809&&&&&&&&&&&&& 809&&&&&&&&&&&&&&&&&&&&& (daemon)
&& absinthed.N94 &7f0caa940b863c901aa9&&&&&&&&&&& 99&&&&&&&&&&&&&& 99&&&&&&&&&&&&&&&&&&&&& (daemon)
filecoordination &fbab576f37a63b56aaa7d8&&&&&&&&&& 226&&&&&&&&&&&&& 226&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&& distnoted &a89af76ec8633ac2bbe99bc2b7964bb0&&&&&&&&&& 137&&&&&&&&&&&&& 137&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&&&&& apsd &94d2f82d775bc279ae608&&&&&&&&&& 373&&&&&&&&&&&&& 373&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&& networkd &f53a6c8a588&&&&&&&&&& 219&&&&&&&&&&&&& 219&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&& aggregated &8c3c991dc4153bc38aee1e&&&&&&&&&& 112&&&&&&&&&&&&& 112&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&& BTServer &c92fbdec9dbd&&&&&&&&&& 522&&&&&&&&&&&&& 522&&&&&&&&&&&&&&&&&&&&& (daemon)
&& fairplayd.N94 &7bd896bd90d05cf1c86a&&&&&&&&&& 210&&&&&&&&&&&&& 210&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&& fseventsd &996cc4caaea8d781b55bce08&&&&&&&&&& 384&&&&&&&&&&&&& 384&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&& imagent &1ea1d07b2f&&&&&&&&&& 586&&&&&&&&&&&&& 586&&&&&&&&&&&&&&&&&&&&& (daemon)
&& mDNSResponder &3ed27a827d97&&&&&&&&&& 295&&&&&&&&&&&&& 295&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&& lockdownd &ba3f1b91af7d5f58dd5bbe&&&&&&&&&& 389&&&&&&&&&&&&& 389&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&&& powerd &2d2ffed5e69638aeba1b92ef124ed861&&&&&&&&&& 174&&&&&&&&&&&&& 174&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&& CommCenter &1f425e1e897d32e8864fdd8eeaa803a8&&&&&&&&& 2212&&&&&&&&&&&& 2212&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&&&&&& notifyd &51c0e03da8a93ac8a595442fcaac531f&&&&&&&&&& 211&&&&&&&&&&&&& 211&&&&&&&&&&&&&&&&&&&&& (daemon)
&&&& ReportCrash &8c32f231b2ed360bb151b2563bcaa363&&&&&&&&&& 337&&&&&&&&&&&&& 337&&&&&&&&&&&&&&&&&&&&& (daemon)
这日志跟我们前面见到的相差很多。
这个一个来自iOS 6的低内存崩溃日志。正如我们前面所说的,低内存崩溃日志与其他类型的崩溃日志很不一样,它们不指向特定的文件和代码行。相反,它们画出了闪退时设备上的内存使用情况的图表。
至少,头部还是跟其他崩溃日志很像的: &提供了 Incident Identifier, CrashReporter Key, Hardware Model, OS Version等信息。
接下来部分是低内存崩溃日志特有的:
Free pages&指可用内存页数。每页大小约是4KB, 上面的日志中,可用内存约为3,872 KB (或者说 3.9 MB)。Purgeable pages&是那部分可被清除或重用的内存。在上面的日志中,是0KB。Largest process是闪退时使用大部分内存的应用名称,在上面的日志中,正是你的应用!Processes显示了闪退时各进程列表,还包含内存使用量。包含进程名 (第一列), 进程唯一标识符(第二名), 进程使用的内存页数(第三列)。最后一列是每个应用的状态。通常,发生闪退的应用的状态是 frontmost。 这里是 Rage Masters, 使用28591 页 (or 114.364 MB) 内存——这内存太多了!
通过,最大进程和frontmost状态的应用是相同的, 而且也是引起低内存闪退的应用进程。但是也可能看到最大进程和 frontmost状态应用不同的例子。比如,如果最大进程是SpringBoard, 忽略它 , 因为 SpringBoard 进程是显示主屏幕的应用,出现在你双击home按钮等情况,而且它是一直活动的。
低内存发生时,iOS向活动的应用发出低内存警告并终止后台应用。如果前台应用仍然继续增长内存,iOS将终止它。
为了查找低内存问题的原因,你必需使用Instruments剖析应用。如果你不知道怎么做,可以看一下我们 一篇关于这个方面的教程.。 :] 另外, 你也可以走捷径,响应低内存警告通知,以解决部分闪退问题。
回到Xcode查看RMLollipopLicker.m文件。 这是实现吃棒棒糖的视图控制器。看看源代码:
#import &RMLollipopLicker.h&
#define COUNT 20
@interface RMLollipopLicker ()
@property (weak, nonatomic) IBOutlet UIProgressView *progressV
@property (weak, nonatomic) IBOutlet UILabel *
@property (weak, nonatomic) IBOutlet UILabel *lickedTimeL
@implementation RMLollipopLicker {
&&& NSOperationQueue *
&&& NSMutableArray *
#pragma mark - Life cycle
- (void)viewDidLoad {
&&& [super viewDidLoad];
&&& self.progressView.progress = 0.0;
&&& self.label.text = [NSString stringWithFormat:@&Tap on run and I'll lick a lollipop %d times!&, COUNT];
&&& self.lickedTimeLabel.text = @&&;
&&& lollipops = [[NSMutableArray alloc] init];
&&& queue = [[NSOperationQueue alloc] init];
- (void)lickLollipop {
&&& NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@&Lollipop& withExtension:@&plist&];
&&& NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:fileURL];
&&& NSString *lollipop = [dictionary objectForKey:@&Lollipop&];
&&& [lollipops addObject:lollipop];
#pragma mark - IBActions
- (IBAction)doneButtonPressed:(id)sender {
&&& [self dismissViewControllerAnimated:YES completion:nil];
- (IBAction)runButtonPressed:(id)sender {
&&& [sender setEnabled:NO];
&&& [queue addOperationWithBlock:^{
&&&&&&& for (NSInteger i = 0 ; i = COUNT) {
&&&&&&&&&&& self.label.text = [NSString stringWithFormat:@&Tap on run and I'll lick a lollipop %d times!&, COUNT];
&&&&&&&&&&& self.progressView.progress = 0.0;
&&&&&&&&&&& [sender setEnabled:YES];
当用户点击运行按钮, 应用开始一个背景线程,调用 lickLollipop 方法若干次,然后更新界面反映吃棒棒糖的数量。 lickLollipop 方法从属性列表文件(PLIST)文件读取一个长字符串,然后添加到数组上。这些数据并不重要, 能在不影响用户体验的前提下重新创建。
利用每种能够清除和重建数据而不影响用户体验的情况是好习惯。这样能够方便地释放内存,减少低内存警告。
那么,如何提高代码质量呢? 实现 didReceiveMemoryWarning 方法,像下面这样处理数据:
-(void)didReceiveMemoryWarning {
&&& [lollipops removeAllObjects];
&&& [super didReceiveMemoryWarning];
万岁,你研究了4个闪退案例! 你的应用更完善了,并且学到了一些重要的调试技巧。
你可以到下载改进后的项目代码。
你喜欢iOS崩溃日志揭秘吗? 希望你能将学到的运用到你自己的应用中,也希望你能处理闪退,使你的应用更强壮!
如果你对本教程或崩溃日志有问题或意见,可以在下面发表评论。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:131634次
积分:1828
积分:1828
排名:第10508名
原创:27篇
转载:152篇
评论:14条

我要回帖

更多关于 iphone批量删除短信 的文章

 

随机推荐