小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

iOS應(yīng)用崩潰日志分析

 昵稱2735774 2015-06-25
【獲取方法:1:設(shè)備與電腦上的iTunes Store同步后,會將崩潰日志保存在電腦上Mac OS X:~/Library/Logs/CrashReporter/MobileDevice/ ;2:將設(shè)備與Mac連接,從xcode-window-devices-view device logs-this device查看,然后右鍵選擇左邊的崩潰日志,點擊Export Log下載日志;3:應(yīng)用提交到App Store后,你也能從 iTunes Connect 獲取到用戶的崩潰日志;4:上傳app到iTunes Store被駁回時,可能會給你的郵件附帶crash文件;
【步驟:使用symbolicatecrash工具,對版本的.dSYM文件、app包及crash日志,生成符號化之后的日志】
【符號化之后的日志】

轉(zhuǎn)自raywenderlich
作為一名應(yīng)用開發(fā)者,你是否有過如下經(jīng)歷?
為確保你的應(yīng)用正確無誤,在將其提交到應(yīng)用商店之前,你必定進(jìn)行了大量的測試工作。它在你的設(shè)備上也運行得很好,但是,上了應(yīng)用商店后,還是有用戶抱怨會閃退 !
如果你跟我一樣是個完美主義者,你肯定想將應(yīng)用做到盡善盡美。于是你打開代碼準(zhǔn)備修復(fù)閃退的問題……但是,從何處著手呢?
這時iOS崩潰日志派上用場了。在大多數(shù)情況下,你能從中了解到關(guān)于閃退的詳盡、有用的信息。
通過本教程,你將學(xué)習(xí)到一些常見的崩潰日志案例,以及如何從開發(fā)設(shè)備和iTunes Connect上獲取崩潰日志文件。你還將學(xué)習(xí)到符號化( symbolication)【、“符號化”是指對于指令、指令地址、常數(shù)、變量、寄存器等,在屏幕上均用表義性和可讀性很強(qiáng)的符號來顯示,從日志追蹤到代碼 。你還將學(xué)習(xí)調(diào)試一個在待定情況下會閃退的應(yīng)用。
讓我們開始動手吧!
什么是崩潰日志,從哪里能得它?
iOS設(shè)備上的應(yīng)用閃退時,操作系統(tǒng)會生成一個崩潰報告,也叫崩潰日志,保存在設(shè)備上。
崩潰日志上有很多有用的信息,包括應(yīng)用是什么情況下閃退的。通常,上面有每個正在執(zhí)行線程的完整堆棧跟蹤信息,所以你能從中了解到閃退發(fā)生時各線程都在做什么,并分辨出閃退發(fā)生在哪個線程上。
有幾種方法可以從設(shè)備上獲取崩潰日志。
1:設(shè)備與電腦上的iTunes Store同步后,會將崩潰日志保存在電腦上。根據(jù)電腦操作系統(tǒng)的不同,崩潰日志將保存在以下位置:
Mac OS X:~/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>:


2:當(dāng)用戶抱怨閃退時,你可以要求他讓設(shè)備與iTunes同步,并根據(jù)操作系統(tǒng)的不同,到上述位置把崩潰日志下載下來,然后通過電子郵件發(fā)送給你。
你必需盡量獲取用戶設(shè)備生成的所有崩潰日志。因為崩潰日志越多,就越容易診斷問題所在!
另外,如果你裝了Xcode,也能很容易通過Xcode從你的設(shè)備上獲得崩潰日志。將iOS設(shè)備連接到電腦上,然后打開Xcode。從菜單欄上選擇 Window  菜單, 然后選擇 Organizer (快捷方式是 Shift-CMD-2).
在 Organizer 窗口上, 選中 Devices 標(biāo)簽欄. 在左側(cè)的導(dǎo)航面板上,選中 Device Logs, 如下圖所示:
看看上圖,左側(cè)有好幾個 Device Logs 菜單項。 LIBRARY 下面的Device Logs是你所有設(shè)備(曾經(jīng)連接到Xcode的)的日志 。每個設(shè)備下面的 Device Logs 是對應(yīng)設(shè)備的日志。

3:應(yīng)用提交到App Store后,你也能從 iTunes Connect 獲取到用戶的崩潰日志. 登錄到 iTunes Connect 上, 選擇 Manage Your Applications, 點擊相應(yīng)的應(yīng)用, 點擊應(yīng)用圖標(biāo)下面的 View Details 按鈕, 然后點擊右欄Links部分的  Crash Reports 。
如果沒有崩潰日志,試試點擊Refresh 按鈕刷新一下。如果你的應(yīng)用還賣得不多,或者剛上架不久,iTunes Connect賬號上也可能還沒有任何崩潰日志?!究隙ㄐ枰卿涃~號】
如果iTunes Connect上有崩潰日志,你將看到如下圖:
有時,盡管有用戶報告閃退,你仍然看不到崩潰報告。這時,最好讓用戶直接把崩潰報告發(fā)送給你。
什么情況下會產(chǎn)生崩潰日志?
兩種主要情況會產(chǎn)生崩潰日志:
1.應(yīng)用違反操作系統(tǒng)規(guī)則。
2.應(yīng)用中有Bug。
違反iOS規(guī)則包括在啟動、恢復(fù)、掛起、退出時watchdog超時、用戶強(qiáng)制退出和低內(nèi)存終止。讓我們詳細(xì)了解一下吧。
Watchdog 超時機(jī)制
從iOS 4.x開始,退出應(yīng)用時,應(yīng)用不會立即終止,而是退到后臺。但是,如果你的應(yīng)用響應(yīng)不夠快,操作系統(tǒng)有可能會終止你的應(yīng)用,并產(chǎn)生一個崩潰日志。這些事件與下列UIApplicationDelegate方法相對應(yīng):
application:didFinishLaunchingWithOptions:
applicationWillResignActive:
applicationDidEnterBackground:
applicationWillEnterForeground:
applicationDidBecomeActive:
applicationWillTerminate:
上面所有這些方法,應(yīng)用只有有限的時間去完成處理。如果花費時間太長,操作系統(tǒng)將終止應(yīng)用。
注意: 如果你沒有把需要花費時間比較長的操作(如網(wǎng)絡(luò)訪問)放在后臺線程上就很容易發(fā)生這種情況。關(guān)于如果避免這種情況的信息,請參考我們的另外兩篇教程: Grand Central Dispatch 和 NSOperations。
用戶強(qiáng)制退出
iOS 4.x開始支持多任務(wù)。如果應(yīng)用阻塞界面并停止響應(yīng), 用戶可以通過在主屏幕上雙擊Home按鈕來終止應(yīng)用。此時,操作應(yīng)用將生成一個崩潰日志。
注意: 雙擊Home按鈕后,你將看到運行過的所有應(yīng)用。那些應(yīng)用不一定是正在運行,也不一定是被掛起。
通常,用戶點擊Home按鈕時,應(yīng)用將在后臺保留約10分鐘,然后操作系統(tǒng)自動將其終止。 所以雙擊Home按鈕顯示的應(yīng)用列表只是表明那是一系列過去打開過的應(yīng)用。刪除那些應(yīng)用的圖標(biāo)不會產(chǎn)生任何崩潰日志。
低內(nèi)存終止
子類化UIViewController時,你或許已經(jīng)注意到didReceiveMemoryWarning方法。
在前臺運行的應(yīng)用擁有訪問和使用內(nèi)存的最高優(yōu)化級。然而,這并不意味著該應(yīng)用能使用設(shè)備的所有可用內(nèi)存 ——每個應(yīng)用只能使用一部分可用內(nèi)存。
當(dāng)內(nèi)存使用達(dá)到一定程度時,操作系統(tǒng)將發(fā)出一個 UIApplicationDidReceiveMemoryWarningNotification 通知。同時,調(diào)用 didReceiveMemoryWarning 方法。
此時,為了讓應(yīng)用繼續(xù)正常運行,操作系統(tǒng)開始終止在后臺的其他應(yīng)用以釋放一些內(nèi)存。所有后臺應(yīng)用被終止后,如果你的應(yīng)用還需要更多內(nèi)存,操作系統(tǒng)會將你的應(yīng)用也終止掉,并產(chǎn)生一個崩潰日志。而在這種情況下被終止的后臺應(yīng)用,不會產(chǎn)生崩潰日志。
注意: 根據(jù) 蘋果文檔, Xcode不會自動添加低內(nèi)存日志。你必需手動獲取日志。 然而,根據(jù)我的個人經(jīng)驗,使用 Xcode 4.5.2, 低內(nèi)存日志也會自動導(dǎo)入,只是”Process”和”Type”屬性都被標(biāo)為Unknown(未知)。
另外,值得一提的是在極短時間內(nèi)分配一大塊內(nèi)存將給系統(tǒng)內(nèi)存帶來巨大負(fù)擔(dān)。這樣,也會產(chǎn)生內(nèi)存警告的通知。
應(yīng)用中有Bug
如你所想,大多數(shù)閃退都是由于應(yīng)用中有Bug,因此大多數(shù)崩潰日志的產(chǎn)生都是因為應(yīng)用中的Bug。Bug的種類的有很多。
在本教程的后半部分,你將通過調(diào)試一個會產(chǎn)生崩潰日志的含有Bug的應(yīng)用,學(xué)習(xí)如何找到問題所在并進(jìn)行修復(fù)!
崩潰日志的實例
讓我們看看一個崩潰日志的實例,以使你在處理一些實際問題之前心里有譜。
事不宜遲,見見你的新朋友吧:
這報告看起來像天書。:) 我們分幾部分來解讀吧:
(1) 進(jìn)程信息
第一部分是閃退進(jìn)程的相關(guān)信息。
Incident Identifier是崩潰報告的唯一標(biāo)識符。
CrashReporter Key 與設(shè)備標(biāo)識相對應(yīng)的唯一鍵值。雖然它不是真正的設(shè)備標(biāo)識符,但也是一個非常有用的情報:如果你看到100個崩潰日志的CrashReporter Key值都是相同的,或者只有少數(shù)幾個不同的CrashReport值,說明這不是一個普遍的問題,只發(fā)生在一個或少數(shù)幾個設(shè)備上
Hardware Model 標(biāo)識設(shè)備類型。 如果很多崩潰日志都是來自相同的設(shè)備類型,說明應(yīng)用只在某特定類型的設(shè)備上有問題。上面的日志里,崩潰日志產(chǎn)生的設(shè)備是iPhone 4s。
Process 是應(yīng)用名稱。中括號里面的數(shù)字是閃退時應(yīng)用的進(jìn)程ID。
接下來幾行不言自明,無需贅述。
(2) 基本信息
這部分給出了一些基本信息,包括閃退發(fā)生的日期和時間,設(shè)備的iOS版本。如果有很多崩潰日志都來自iOS 6.0,說明問題只發(fā)生在iOS 6.0上。
(3) 異常
在這部分,你可以看到閃退發(fā)生時拋出的異常類型。還能看到異常編碼和拋出異常的線程。根據(jù)崩潰報告類型的不同,在這部分你還能看到一些另外的信息。
(4) 線程回溯
這部分提供應(yīng)用中所有線程的回溯日志。 回溯是閃退發(fā)生時所有活動幀清單。它包含閃退發(fā)生時調(diào)用函數(shù)的清單。看下面這行日志:
它包括四列:
幀編號—— 此處是2。
二進(jìn)制庫的名稱 ——此處是 XYZLib.
調(diào)用方法的地址 ——此處是 0x34648e88.
第四列分為兩個子列,一個基本地址和一個偏移量。此處是0×83000 + 8740, 第一個數(shù)字指向文件,第二個數(shù)字指向文件中的代碼行。
(5) 線程狀態(tài)
這部分是閃退時寄存器中的值。一般不需要這部分的信息,因為回溯部分的信息已經(jīng)足夠讓你找出問題所在。
(6) 二進(jìn)制映像
這部分列出了閃退時已經(jīng)加載的二進(jìn)制文件。
符號化Symbolication
第一次看到崩潰日志上的回溯時,你或許會覺得它沒什么意義。我們習(xí)慣使用方法名和行數(shù),而非像這樣的神秘位置:
將這些十六進(jìn)制地址轉(zhuǎn)化成方法名稱和行數(shù)的過程稱之為符號化。

從Xcode的Organizer窗口獲取崩潰日志后過幾秒鐘,崩潰日志將被自動符號化。上面那行被符號化后的版本如下 :
Xcode符號化崩潰日志時,需要訪問與App Store上對應(yīng)的應(yīng)用二進(jìn)制文件以及生成二進(jìn)制文件時產(chǎn)生的 .dSYM 文件。必需完全匹配才行。否則,日志將無法被完全符號化。
所以,保留每個分發(fā)給用戶的編譯版本非常重要。提交應(yīng)用前進(jìn)行歸檔時,Xcode將保存應(yīng)用的二進(jìn)制文件??梢栽赬code Organizer的Archives標(biāo)簽欄下找到所有已歸檔的應(yīng)用文件。
在發(fā)現(xiàn)崩潰日志時,如果有相匹配的.dSYM文件和應(yīng)用二進(jìn)制文件,Xcode會自動對崩潰日志進(jìn)行符號化。如果你換到別的電腦或創(chuàng)建新的賬戶,務(wù)必將所有二進(jìn)制文件移動到正確的位置,使Xcode能找到它們。
注意: 你必需同時保留應(yīng)用二進(jìn)制文件和.dSYM文件才能將崩潰日志完整符號化。每次提交到iTunes Connect的構(gòu)建都必需歸檔。
.dSYM文件和二進(jìn)制文件是特定綁定于每一次構(gòu)建和后續(xù)構(gòu)建的,即使來自相同的源代碼文件,每一次構(gòu)建也與其他構(gòu)建不同,不能相互替換。
如果你使用Build 和 Archive 命令,這些文件會自動放在適當(dāng)位置。 如果不是使用Build 和 Archive命令,放在Spotlight能夠搜索到的位置(比如Home目錄)即可。)
低內(nèi)存閃退
因為低內(nèi)存崩潰日志與普通崩潰日志略有不同,所以本教程特別分開說明一下。
iOS設(shè)備檢測到低內(nèi)存時,虛擬內(nèi)存系統(tǒng)發(fā)出通知請求應(yīng)用釋放內(nèi)存。這些通知發(fā)送到所有正在運行的應(yīng)用和進(jìn)程,試圖收回一些內(nèi)存。
如果內(nèi)存使用依然居高不下,系統(tǒng)將會終止后臺線程以緩解內(nèi)存壓力。如果可用內(nèi)存足夠,應(yīng)用將能夠繼續(xù)運行而不會產(chǎn)生崩潰報告。否則,應(yīng)用將被iOS終止,并產(chǎn)生低內(nèi)存崩潰報告。
低內(nèi)存崩潰日志上沒有應(yīng)用線程的堆?;厮?。相反,上面顯示的是以內(nèi)存頁數(shù)為單位的各進(jìn)程內(nèi)存使用量。(在撰寫本文的時候,一個內(nèi)存頁的大小是4KB。)
被iOS因釋放內(nèi)存頁終止的進(jìn)程名稱后面你會看到j(luò)ettisoned 字樣。如果看到它出現(xiàn)在你的應(yīng)用名稱后面,說明你的應(yīng)用因使用太多內(nèi)存而被終止了。
低內(nèi)存崩潰日志看起來像這樣:
當(dāng)應(yīng)用發(fā)生低內(nèi)存閃退時,你必需看看應(yīng)用中內(nèi)存使用的方式,以及是如何處理低內(nèi)存警告的。你可以使用Instruments工具中使用Allocations 和 Leaks來發(fā)現(xiàn)內(nèi)存分配問題和內(nèi)存泄漏問題。如果你不知道如何利用 Instruments 檢查內(nèi)存問題,可以看看這個教程 。
還有,別忘記虛擬內(nèi)存! Instruments工具的Leaks 和 Allocations 不能跟蹤顯存使用情況。必需使用 VM Tracker 才能查看顯存使用情況。
VM Tracker 默認(rèn)是關(guān)閉的。打開Instrument,手動 選中Automatic Snapshotting 標(biāo)志或者按下Snapshot Now 按鈕。
本教程后面將會學(xué)習(xí)如何研究低內(nèi)存崩潰日志。
異常編碼
在研究真實閃退場景之前,還有一點需要重點介紹一下:就是那些有趣的異常編碼 。
你可以在報告的異常部分——前面代碼的第3部分找到異常編碼。有些編碼比較常見。
通常,異常編碼以一些文字開頭,緊接著是一個或多個十六進(jìn)制值,此數(shù)值正是說明閃退根本性質(zhì)的所在。  從這些編碼中,可以區(qū)分出閃退是因為程序錯誤、非法內(nèi)存訪問或者是其他原因。
下面是一些常見的異常編碼:
0x8badf00d: 讀做 “ate bad food”! (把數(shù)字換成字母,是不是很像 :p)該編碼表示應(yīng)用是因為發(fā)生watchdog超時而被iOS終止的。  通常是應(yīng)用花費太多時間而無法啟動、終止或響應(yīng)用系統(tǒng)事件。
0xbad22222: 該編碼表示 VoIP 應(yīng)用因為過于頻繁重啟而被終止。
0xdead10cc: 讀做 “dead lock”!該代碼表明應(yīng)用因為在后臺運行時占用系統(tǒng)資源,如通訊錄數(shù)據(jù)庫不釋放而被終止 。
0xdeadfa11: 讀做 “dead fall”! 該代碼表示應(yīng)用是被用戶強(qiáng)制退出的。根據(jù)蘋果文檔, 強(qiáng)制退出發(fā)生在用戶長按開關(guān)按鈕直到出現(xiàn) “滑動來關(guān)機(jī)”, 然后長按 Home按鈕。強(qiáng)制退出將產(chǎn)生 包含0xdeadfa11 異常編碼的崩潰日志, 因為大多數(shù)是強(qiáng)制退出是因為應(yīng)用阻塞了界面。
注意: 在后臺任務(wù)列表中關(guān)閉已掛起的應(yīng)用不會產(chǎn)生崩潰日志。 一旦應(yīng)用被掛起,它何時被終止都是合理的。所以不會產(chǎn)生崩潰日志。)
大展身手的時候到了!好了! 你已經(jīng)學(xué)習(xí)了所有分析崩潰日志和修復(fù)錯誤的基礎(chǔ)知識!
假設(shè)你剛進(jìn)入Rage-O-Rage有限公司工作。該公司有一個在App Store上熱銷的應(yīng)用,叫 Rage Masters。
你的老板安迪要你幫忙解決幾個用戶經(jīng)常抱怨閃退問題。你的任務(wù)就是研究這些閃退,符號化用戶提供的崩潰日志,查找問題所在,并修復(fù)之。
你可以從 這里下載應(yīng)用的源代碼。
注意: 如果你想自己重新生成崩潰報告,請遵照以下指引:
1.下載源碼然后在Xcode中打開工程文件。
2.使用正確的provisioning profile連接到iOS設(shè)備。
3.從Xcode工具欄上選擇iOS設(shè)備——不是模擬器作為target,然后構(gòu)建應(yīng)用。
4.當(dāng)你在設(shè)備上到默認(rèn)頁面(應(yīng)用的全屏圖片)時,立即在Xcode上點擊停止按鈕。
5.關(guān)閉 Xcode。
6.在設(shè)備上直接打開應(yīng)用。
7.測試場景,完成后連接設(shè)備到電腦上,通過Xcode獲取崩潰日志。)
場景 1: 糟糕的代碼
一封來自用戶的郵件: “大哥,你的應(yīng)用就是一坨屎! 我將其下載到我自己的iPod Touch和iPhone上,還下載到我兒子的iPod Touch上。在所有的設(shè)備上,都是還沒打開就閃退了……”
別一封來自用戶的郵件說, “我下載了你們的應(yīng)用,一打開就閃退。真悲催…”
另一封郵件說得更明確:”你們的應(yīng)用不能運行。我把它下載到我和妻子的設(shè)備上。所有設(shè)備都是 一打開就閃退了…”
好吧,別灰心! 這些意見藏著什么玄機(jī)呢?讓我們看看崩潰日志吧:
發(fā)現(xiàn)問題了嗎? 異常編碼是0x000000008badf00d,還有后面的報告:
這說明應(yīng)用在啟動時就閃退了,iOS的watchdog機(jī)制終止了應(yīng)用。帥! 找到問題了,但是為什會發(fā)生這樣的事呢?
接著往下看日志。 從下向上讀回溯日志。最底下的幀 (frame 25: libdyld.dylib)是最先調(diào)用的,然后是幀24, Rage Masters, main (main.m:16) ,依此類推。
跟應(yīng)用源代碼相關(guān)的幀是最重要的。忽略掉系統(tǒng)庫和框架。下一個與代碼相關(guān)的幀是:
應(yīng)用在執(zhí)行RMAppDelegate (RMAppDelegate.m:35)類application:didFinishLaunchingWithOptions: 方法第35 行代碼時閃退。打開Xcode看看那行代碼:
就是它了! 同步調(diào)用web服務(wù)?!【用異步】 在主線程上?! 在 application:didFinishLaunchingWithOptions: 方法上?!! 誰寫的代碼呀?!
Network calls on the main thread makes kittens sad.
不管如何,問題得你來修復(fù)了。這個調(diào)用必需異步進(jìn)行,甚至更理想的情況是,在application:didFinishLaunchingWithOptions:返回YES之后的其他部分再執(zhí)行Web服務(wù)。
在其他地方調(diào)用可能需要比較多的修改。當(dāng)下,我們只要使應(yīng)用不閃退就行??梢栽谌蘸笤賹崿F(xiàn)更好的設(shè)計。 將上面那行討厭的代碼(及其下面的三行代碼)換成下面這個異步的版本吧:
 場景 2: 無法響應(yīng)事件的按鈕
一名用戶說: “我不能將某個rage master添加到書簽里面。我想添加的時候應(yīng)用就閃退…”
用一名用戶說 :”書簽不能用 … 在詳細(xì)頁面上,點擊書簽按鈕,應(yīng)用就閃退了!”
上面的抱怨說得不是很清楚,引起問題的原因肯定有多樣。看看崩潰日志:
異常代碼是SIGABRT。通常,  SIGABRT 異常是由于某個對象接收到未實現(xiàn)的消息引起的。 或者,用簡單的話說,在某個對象上調(diào)用了不存在的方法。
這種情況一般不會發(fā)生,因為A對象調(diào)用了B方法,如果B方法不存在,編譯器會報錯。但是,如果你是使用selector間接調(diào)用方法的,編譯器則無法檢測對象是否存在該方法了。
回到崩潰日志。它指出閃退發(fā)生在編號為0的線程上。 這意味著很可能是在主線程上調(diào)用了某個對象沒有實現(xiàn)的方法。
如果你接著閱讀回溯日志,會發(fā)現(xiàn)跟你的代碼相關(guān)的只有幀22, main.m:16. 這沒有多大幫助。 
繼續(xù)向上查看框架調(diào)用,出現(xiàn)這個:
這不是你自己寫的代碼。但至少它確認(rèn)了是對象調(diào)用了一個沒有實現(xiàn)的方法。
回到RMDetailViewController.m文件, 因為那是書簽按鈕實現(xiàn)動作的地方。 找到書簽功能代碼:
看起來沒什么問題,再檢查一下storyboard (XIB文件) ,確認(rèn)按鈕連接的正確性。
就是它了! 在 MainStoryboard.storyboard,按鈕連接的是 bookmarkButtonPressed: 而不是bookmarkButtonPressed (注意后面的分號說明方法有一個參數(shù))。 只要將上面的方法簽名修改成這樣就能修復(fù)問題了:
當(dāng)然,你也可以簡單地在XIB文件上刪除錯誤的連接,然后重新連接方法,使XIB文件連接到正確的方法上。兩者方法都行。
又處理了一個閃退問題,好樣的。
場景 3: 表格上的Bug
另一用戶抱怨道, “在書簽視圖上無法刪除書簽…” 還有另一用戶抱怨同樣的問題, “當(dāng)我試圖刪除書簽時,應(yīng)用閃退…”
這些郵件沒什么作用,還是看看崩潰日志!
這看起來跟前面那個崩潰日志很像。是另一個SIGABRT 異常。 你可能想知道是否是相同的問題:發(fā)送信息到一個沒有實現(xiàn)相應(yīng)方法的對象?
讓我們從回溯日志看看哪些方法被調(diào)用了。從底部開始,你的源代碼最后被調(diào)用的是幀 6:
這是UITableViewDataSource 的一個方法. 呵呵?! 毫無疑問蘋果已經(jīng)實現(xiàn)了該方法 —— 你可以重載它, 但不像是還沒有實現(xiàn)。而且,這是個可選的委派方法。 所以問題不是調(diào)用了一個沒有實現(xiàn)的方法。
再看看上面的幾個幀:
幀 5, UITableView調(diào)用了它自己的另一個方法 deleteRowsAtIndexPaths:withRowAnimation: 然后是看起來像蘋果內(nèi)部方法的_endCellAnimationsWithContext: 被調(diào)用。然后Foundation framework發(fā)生異常handleFailureInMethod:object:file:lineNumber:description:.
這些分析結(jié)合用戶的抱怨,看起來是你在處理UITableView刪除行過程中有Bug?;氐絏code。你知道看哪里嗎 ? 能從崩潰日志中判斷出來? 就是RMBookmarksViewController.m文件的第68行:
發(fā)現(xiàn)問題了嗎? 給你點時間,仔細(xì)看一下。
找到了吧! 數(shù)據(jù)源呢? 代碼在表格視圖上刪除了一行,但并沒有修改背后的數(shù)據(jù)源。把上面的代碼替換成下面的就能修復(fù)問題了:
搞定了!走起,討厭的 bug!!
場景 4: 吃棒棒糖時閃退!
用戶郵件說, “當(dāng)rage master吃棒棒糖時應(yīng)用就閃退…” 另一用戶說, “我讓rage master 吃棒棒糖,沒幾次應(yīng)用就閃退了!”
崩潰日志如下:
這日志跟我們前面見到的相差很多。
這個一個來自iOS 6的低內(nèi)存崩潰日志。正如我們前面所說的,低內(nèi)存崩潰日志與其他類型的崩潰日志很不一樣,它們不指向特定的文件和代碼行。相反,它們畫出了閃退時設(shè)備上的內(nèi)存使用情況的圖表。
至少,頭部還是跟其他崩潰日志很像的:  提供了 Incident Identifier, CrashReporter Key, Hardware Model, OS Version等信息。
接下來部分是低內(nèi)存崩潰日志特有的:
Free pages 指可用內(nèi)存頁數(shù)。每頁大小約是4KB, 上面的日志中,可用內(nèi)存約為3,872 KB (或者說 3.9 MB)。
Purgeable pages 是那部分可被清除或重用的內(nèi)存。在上面的日志中,是0KB。
Largest process是閃退時使用大部分內(nèi)存的應(yīng)用名稱,在上面的日志中,正是你的應(yīng)用!
Processes顯示了閃退時各進(jìn)程列表,還包含內(nèi)存使用量。包含進(jìn)程名 (第一列), 進(jìn)程唯一標(biāo)識符(第二名), 進(jìn)程使用的內(nèi)存頁數(shù)(第三列)。最后一列是每個應(yīng)用的狀態(tài)。通常,發(fā)生閃退的應(yīng)用的狀態(tài)是 frontmost。 這里是 Rage Masters, 使用28591 頁 (or 114.364 MB) 內(nèi)存——這內(nèi)存太多了!
通過,最大進(jìn)程和frontmost狀態(tài)的應(yīng)用是相同的, 而且也是引起低內(nèi)存閃退的應(yīng)用進(jìn)程。但是也可能看到最大進(jìn)程和 frontmost狀態(tài)應(yīng)用不同的例子。比如,如果最大進(jìn)程是SpringBoard, 忽略它 , 因為 SpringBoard 進(jìn)程是顯示主屏幕的應(yīng)用,出現(xiàn)在你雙擊home按鈕等情況,而且它是一直活動的。
低內(nèi)存發(fā)生時,iOS向活動的應(yīng)用發(fā)出低內(nèi)存警告并終止后臺應(yīng)用。如果前臺應(yīng)用仍然繼續(xù)增長內(nèi)存,iOS將終止它。
為了查找低內(nèi)存問題的原因,你必需使用Instruments剖析應(yīng)用。如果你不知道怎么做,可以看一下我們 一篇關(guān)于這個方面的教程.。 :] 另外, 你也可以走捷徑,響應(yīng)低內(nèi)存警告通知,以解決部分閃退問題。
回到Xcode查看RMLollipopLicker.m文件。 這是實現(xiàn)吃棒棒糖的視圖控制器??纯丛创a:
當(dāng)用戶點擊運行按鈕, 應(yīng)用開始一個背景線程,調(diào)用 lickLollipop 方法若干次,然后更新界面反映吃棒棒糖的數(shù)量。 lickLollipop 方法從屬性列表文件(PLIST)文件讀取一個長字符串,然后添加到數(shù)組上。這些數(shù)據(jù)并不重要, 能在不影響用戶體驗的前提下重新創(chuàng)建。
利用每種能夠清除和重建數(shù)據(jù)而不影響用戶體驗的情況是好習(xí)慣。這樣能夠方便地釋放內(nèi)存,減少低內(nèi)存警告。
那么,如何提高代碼質(zhì)量呢? 實現(xiàn) didReceiveMemoryWarning 方法,像下面這樣處理數(shù)據(jù):
下一步?
萬歲,你研究了4個閃退案例! 你的應(yīng)用更完善了,并且學(xué)到了一些重要的調(diào)試技巧。
你可以到這里下載改進(jìn)后的項目代碼。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多