為什麼很多 iOS app 都有秒退現象?有什麼好方法避免它?
有哪些好方法避免這種現象嗎?
問題里的「秒退」如果我沒理解錯,應該是指程序顯示完默認啟動圖片後,在初始化階段就崩潰了(也可以叫「閃退」,不過最近「閃退」這個詞已經被廣泛應用於各種程序崩潰情況了,所以可能還是「秒退」更準確?)。
這種情況應和所謂的內存不足關係不大,很少有程序會在初始化時載入大量內容導致崩潰,並且這類問題也很容易在開發階段被發現,所以內存不足造成秒退的可能性低(內存不足退,通常是程序用了一段時間,切換了幾個畫面以後發生的)。
而且秒退是發生在程序剛剛啟動的時候,在開發、蘋果審核階段都沒有被發現的最大可能性就是,這個問題只會發生在老版系統、老版機型上。
對於很多開發者(尤其是個人開發者),進行所有 iOS 版本,所有 iOS 機型覆蓋測試是有難度的,蘋果審核時也只是重點審核該應用在新機器、新版本下的運行情況,並不關注老系統。所以這也就是為什麼會秒退的程序竟然也能通過蘋果的審核。
在新 iOS 上正常的應用,到了老版本 iOS 上秒退最常見原因是系統動態鏈接庫或Framework無法找到。這種情況通常是由於 App 引用了一個新版操作系統里的動態庫(或者某動態庫的新版本)或只有新 iOS 支持的 Framework,而又沒有對老系統進行測試,於是當 App 運行在老系統上時便由於找不到而秒退。解決辦法是等開發人員發現這個問題後升級程序,或由用戶自行升級其操作系統。
還有一種常見的秒退是程序在升級時,修改了本地存儲的數據結構,但是對用戶既存的舊數據沒有做好升級,結果導致初始化時因為無法正確讀取用戶數據而秒退。這類問題通常只需刪除程序後重新安裝一遍就能解決。但缺點是用戶的既存數據會丟失——就算有備份可能也無濟於事,因為備份下來的舊數據還是無法被正確升級。如果舊數據非常重要,那麼就需要聯繫開發人員要求其進行程序修正了。
另一種已經變得不那麼常見的秒退原因是 App 的設置不正確。例如在編譯時沒有編譯 ARMv6 的版本,但是設置里卻允許該 App 運行在 ARMv6 處理器的機器上(如:iPhone 1代,iPhone 3G,iPod touch 1、2代和3代8G版)。這個問題除了等開發人員升級外用戶自己沒什麼辦法解決。當然願意換台新機器是最好的 ;) 這個問題目前已經能夠在提交應用至 App Store 的時候被檢查出來了,因此今後應該不太常見了。
還有一類秒退或是用到 App 里某個功能後必退的原因,是開發時用到了只有新版操作系統才支持的某個方法,而又沒有對該方法是否存在於老系統中做出判斷。例如程序啟動時用到了 Game Center,而沒有判斷用戶的機器是否支持 Game Center,於是就秒退了。
主要的秒退情況就是這麼幾個,這些都是以該 App 新版系統上能正常跑為前提的。
諸如內存不足、BAD_ACCESS 這類問題通常不管在新舊 iOS 上都會存在,如果是由於這類問題造成的秒退通常都能在測試和審核階段被發現,因此並不常見。根絕我的開發經驗 要是排除內存的問題 大部分都是因為多線程的問題 像core data這種不支持多線程的框架 在多線程下同步很麻煩
大部分都是由於未捕獲的異常或者是野指針造成的,絕大部分不是因為內存用量的問題
秒退可以簡單的理解為程序crash, 程序越做越複雜, crash是無法完全避免的,涉及到很多因素,甚至設備本身的內存限制等等,上面幾位都解釋的非常詳細了。
順便提一下apple在這方面做的比較到位的一點,就是直接閃退,對比一下android的做法,你就能發現為什麼蘋果好用了。 Android下面這個crash叫做Force close, 俗稱FC. 因為每次程序crash都不像蘋果一樣閃退,而是彈出一個對話框, 上面寫著程序Force close了,然後只有一個確定按鈕. 這有什麼意義呢? 本來程序崩潰用戶就已經夠煩的了,還非要彈出個對話框,而且只有一個毫無意義的按鈕,讓用戶多一個無聊的操作。 見多了FC會覺得apple的設計太美好了 .急於上線,測試不足,主要是代碼中內存管理出的問題。即使內存不足可以通過釋放緩存等相關操作來解決。
我來說一下這兩天親身遇到的應用程序秒退情況吧。
App 順利被蘋果審核團隊通過,但放出時候後立馬有 iOS4 用戶反映存在秒退的情況。由此可以判斷蘋果的審核團隊可能僅會使用 iOS5 系統來驗證程序是否符合相關法律法規,iOS5 以前的兼容性測試可能沒有做。
就我們的 App 出現 iOS4 環境秒退的原因,在於使用了一條新的 API 導致 iOS4 環境無法識別,直接在初始化的時候退出。解決的辦法是,執行這條新 API 之前對當前允許環境進行判斷,iOS5 的話則執行,否則跳過。
我最近遇到的秒退是發生在覆蓋安裝之後,因為舊版本app的Core Data數據格式與新版app不同,新版程序再讀取舊版數據會直接crash。而讀取core data數據一般在第一個界面的viewwillapear中執行,所以就直接表現為秒退。
其實感覺app review team還是比較寬容的,上線app(詞頻背單詞)的第一個版本存在iOS 5上好些功能不工作,內存泄露等問題,但還是通過了審核。
曾碰到一個秒退的情況大家可能沒見過的:我手工修改了core data使用的sqlite里Z_METADATA表的Z_UUID值,debug時運行正常,但非調式狀態不論device還是模擬器都秒退。解決辦法是用core data的API重新save一個sqlite版本。
徐哲說的挺全面的。
我們犯過一次非常嚴重也是因為野指針的錯誤,導致秒退。
在準備新手引導時,載入資源的路徑為了圖方便,做了本地化(NSLocalizedString),版本更新時,剛好翻譯修改了這個字元串的翻譯,導致路徑找不到,由於這個模塊沒有做好異常處理app一開機就crash了。
但就是有一個國家的語言版本沒有測試。結果這個地區更新了的程序都崩潰了。
我想一般用戶所謂的秒退應該就是程序crash了。
從開發的角度來講一般有以下幾個原因:
1.操作了不該操作的對象,野指針之類的。
2.對內存警告處理不當。
3.主線程UI長時間卡死,被系統殺掉。
4.程序內部異常邏輯沒處理好。
5.sdk版本差異沒處理好。
恩,補充一個。app load時間過長,也會造成閃退。這個碰到過一次,用corona平台開發的一個app,由於初始化時做的工作過多,同時需要連接國外server,不幸那幾天被封了,結果啟動不了。
相比內存不足,更多的是野指針問題。
建議開發者引入crash report工具,可以更準確定位。
談避免要先從發生原因說起。一般閃退原因:1,後台數據或者某個欄位返回空,沒做處理就使用,兼容沒做好,或者類型錯誤。2,APP性能太差,沒做好優化,比如太多的內存泄露,用了一段時間後明顯變慢,然後閃退。3,載入大文件到內存,直接導致內存不足,比如選擇圖片時候載入所有相冊原圖到內存,顯示進行選擇,如果有些妹子相冊上千張圖片,直接爆了,閃退。4,系統版本兼容,比如你用了iOS8才出的API,到iOS7手機運行,執行到這塊如果不做判斷處理必定崩潰。
至於避免閃退肯定就結合閃退原因依次調整咯,手機打字,這塊說起來太多,哈哈,有興趣下次交流。
其實可以做線上錯誤統計,目前有很多免費平台,友盟騰訊都有相關服務,可以根據統計數據結合dSYM文件進行分析,網上也有分析工具,定位出錯的代碼,再優化,哈哈,樓主加油
我覺得大多數是由於後端返回的數據為空的情況下,iOS沒有做判斷就直接往下執行,這樣必然崩潰
大多數情況是由於內存用量過大 memory warning 系統開始 kill process 和一些. 當成訪問到這寫 被 kill 的 實例 就是 異常 導致 crash
典型的秒退:NSLog(@"%@",indexPath.row);
在iphone 3gs上遇到過秒退,未越獄版本,原因之一定位為軟體授權。
驗證方式:使用APPLE ID: aaa下載安裝軟體,切換到APPLE ID:bbb,則之前aaa下載的軟體就會出現秒退。
以前經常碰到就是沒有處理好nil,和指針
就是閃退問題:可能有以下原因:
1、應用程序自身漏洞:
開發的應用程序代碼存在缺陷,造成大多數設備在運行該程序時會出現閃退的情況。這種情況需要開發者進行解決。
2、設備問題:
設備問題主要包括:系統固件版本不支持、系統配置(CPU、RAM等)不支持。這種情況表現為部分設備能正常運作該程序,而其他設備會閃退。
閃退對應用來說是很致命的,需要儘可能的避免或者說減少,這就需要做充分全面的測試,這也是我們選擇第三方測試的其中一個原因。
TestBird-APP和手游測試專家是正在使用的一家自動化測試平台
還有一種可能是推送JPUSH的問題,自從接了極光推送一堆莫名閃退,日誌列印也全是顯示這個問題
推薦閱讀:
※怎樣利用 iPad 學習?
※64 位的 iOS 7 系統和 A7 晶元是否表明蘋果可能要推出堪比家用遊戲機 (console) 的 Apple TV?
※哪些 iOS 應用可以做到在圖片上添加文字?
※自己的 iOS 遊戲被人抄襲了,而且抄襲得非常精美,效果甚至超過了原作,自己能怎麼辦?
※iOS 設計的神細節有哪些?