⑴ 如何針對app crash進行專項測試,測試中用到了哪些輔助工具
一、如何獲得crash日誌
當一個iOS應用程序崩潰時,系統會創建一份crash日誌保存在設備上。這份crash日誌記錄著應用程序崩潰時的信息,通常包含著每個執行線程的棧調用信息(低內存閃退日誌例外),對於開發人員定位問題很有幫助。
如果設備就在身邊,可以連接設備,打開Xcode - Window - Organizer,在左側面板中選擇Device Logs(可以選擇具體設備的Device Logs或者Library下所有設備的Device Logs),然後根據時間排序查看設備上的crash日誌。這是開發、測試階段最經常採用的方式。
如果應用程序已經提交到App Store發布,用戶已經安裝使用了,那麼開發者可以通過iTunes Connect(Manage Your Applications - View Details - Crash Reports)獲取用戶的crash日誌。不過這並不是100%有效的,而且大多數開發者並不依賴於此,因為這需要用戶設備同意上傳相關信息,詳情可參見iOS: Providing Apple with diagnostics and usage information摘要。
考慮到並不是所有iphone用戶都允許自動發送診斷報告(crash日誌),而且對於部分提交到Apple得crash日誌,開發者還需要手動去拉取,然後找到對應的符號文件進行解析——這是一件很繁瑣的事情。所以實際項目開發中,通常接入現有的crash收集工具(參考1,參考2),或者自己編寫一個進行自動化收集、解析和統計匯總。
二、如何解析crash日誌
當獲得一份crash日誌時,我們需要將初始展示的十六進制地址等原始信息映射為源代碼級別的方法名稱和代碼行數,使其對開發人員可讀。這個過程稱為符號化解析。要成功地符號化解析一份crash日誌,我們需要有對應的應用程序二進制文件以及符號(.dSYM)文件。
如果處於開發調試階段,通常Xcode都能匹配到crash日誌對應的二進制文件和符號文件,所以能夠幫我們自動解析。
如果處於測試階段,測試人員已經安裝了不同的版本(比如alpha、beta版本),那麼需要保存好對應版本的二進制文件和符號文件,以便在應用程序崩潰時對crash日誌進行解析。對於這種場景下產生的crash日誌,只需要將.crash文件、.app文件和.dSYM文件三者放在同一個目錄下,然後將.crash文件拖放到Xcode - Window - Organizer中左側面板Library下的Device Logs中,即可進行解析。
如果要提交發布,那麼我們通常會先執行Clean,再Build,最後通過Proct - Archive來打包。這樣,Xcode會將二進制文件和符號文件歸檔在一起,可以通過Organizer中的Archives進行瀏覽。
這里是一份關於如何解析crash日誌的討論:http://stackoverflow.com/questions/1460892/symbolicating-iphone-app-crash-reports 。
三、如何分析crash日誌
在分析一份crash日誌之前,如果開發人員對於常見的錯誤類型有所了解,那定是極好的。
crash日誌的產生來源於兩種問題:違反iOS策略被幹掉,以及自身的代碼bug。
1. iOS策略
1.1 低內存閃退
前面提到大多數crash日誌都包含著執行線程的棧調用信息,但是低內存閃退日誌除外,這里就先看看低內存閃退日誌是什麼樣的。
我們使用Xcode 5和iOS 7的設備模擬一次低內存閃退,然後通過Organizer查看產生的crash日誌,可以發現Process和Type都為Unknown:
而具體的日誌內容如下:
第一部分是崩潰信息,包括識別標識、軟硬體信息和時間信息等。
第二部分是內存頁分配信息,以及當前佔用內存最多的進程,上圖中為crashTypeDemo。
第三部分是具體的進程列表,描述著每個進程使用內存的情況以及當前狀態。在較早的版本中可以在某些進程後面看到「jettisoned」字樣,表明這些進程使用過多內存被終止了,而現在我們看到的是「vm-pageshortage」字樣。
當iOS檢測到內存過低時,它(的VM系統)會發出低內存警告通知,嘗試回收一些內存;如果情況沒有得到足夠的改善,iOS會終止後台應用以回收更多內存;最後,如果內存還是不足,那麼正在運行的應用可能會被終止掉。
所以,我們的應用應該合理地響應系統拋出來的低內存警告通知,對一些緩存數據和可重新創建的對象進行釋放,同時要避免出現內存泄露等問題。
低內存閃退是由iOS策略決定終止應用程序運行的,同樣基於iOS策略的還有Watchdog超時和用戶強制退出。
1.2 Watchdog超時
Apple的iOS Developer Library網站上,QA1693文檔中描述了Watchdog機制,包括生效場景和表現。如果我們的應用程序對一些特定的UI事件(比如啟動、掛起、恢復、結束)響應不及時,Watchdog會把我們的應用程序幹掉,並生成一份響應的crash報告。
這份crash報告的有趣之處在於異常代碼:「0x8badf00d」,即「ate bad food」。
如果說特定的UI事件比較抽象,那麼用代碼來直接描述的話,對應的就是(創建一個工程時Xcode自動生成的)UIApplicationDelegate的幾個方法:
所以當遇到Watchdog日誌時,可以檢查下上圖幾個方法是否有比較重的阻塞UI的動作。
QA1693舉的例子是在主線程進行同步網路請求。如果我們是在公司的Wifi環境下使用則一切順利,但當應用程序發布出去面向很大范圍的用戶,在各種網路環境下運行,則不可避免地會出現一片Watchdog超時報告。
另一種可能出現問題的場景就是數據量比較大的情況下進行的資料庫版本遷移(同樣是在主線程上),這也是促使我寫這篇總結的一個直接因素。
⑵ iphone開發需要什麼
開發環境的要求
硬體:
1.蘋果電腦, 必須是基於Intel的Macintosh計算機。
2.iPhone或iPod Touch,主要用來測試編寫好的程序。
軟體:
1.蘋果系統MacOS。
2.iPhone SDK(請從http://developer.apple.com/iphone/下載最新版SDK),SDK中包含蘋果公司的集成開發環境Xcode,iPhone模擬器及其它一些開發工具。
開發環境的簡單介紹
開發環境主要包括
Xcode (主要開發工具)
Interface Builder (界面快速設計工具)
iPhone Simulator (iPhone模擬器)
SDK(Software Development Kit,軟體開發工具包)
Xcode簡單介紹
開發iPhone OS及Mac OS X應用,需要在Mac OS X運行Xcode開發工具
Xcode是Apple的開發工具套件,支持項目管理、編輯代碼、構建可執行程序、代碼級調試、代碼的版本管理、性能調優等等
Interface Builder 簡單介紹
可視化地設計應用程序的用戶界面。
從Interface Builder的控制項庫中通過拖拽創建諸如窗口,視圖,菜單,按鈕等
可視化的設置控制項屬性,建立各控制項之間的連接;
保存後的nib文件包括了控制項對象,控制項配置,以及控制項布局等信息,程序載入nib文件時根據這些信息創建對象。
Xcode 與 Interface Builder 的聯系
同時使用Xcode和Interface Builder工具,簡化代碼,便於維護,加快開發
使用Xcode來設計程序的邏輯,使用Interface Builder 來設計程序的界面。
關鍵字IBOutlet和IBAction在Xcode中用來聲明屬性和方法,在Interface Builder中與這些聲明建立連接。
iPhone模擬器
iPhone模擬器是可以在電腦上部署和測試你的應用程序的目標平台
iPhone模擬器提供了類iPhone的環境,通過菜單選項,可以模擬屏幕鎖,屏幕轉向,內存警告等功能
因為電腦沒有提供一些必要硬體,所以iPhone模擬器也有功能限制
iPhone模擬器
功能限制:
✕ 不能使用GPS定位
✕ 不能使用加速計
✕ 不支持超過2個手指的觸摸的多點觸摸
✕ 不能打電話
✕ 不能使用3G網路
✕ 不能使用相機和麥克風
✕ 僅提供一些原裝程序如Safari,Contact,Photos,Settings
✕ 無法測試程序對iPhone CPU和內存的消耗情況
SDK -Software Development Kit,軟體開發工具包。
為iPhone平台,Mac OS X系統編寫的軟體開發包和軟體框架。使用它提供的類和API等其它資源來快速開發針對特定硬體平台和操作系統的程序。
SDK有不同平台的版本(如iPhone平台,Mac OS X平台)和同一平台的不同版本。可以讓我們開發部署不同平台和同一平台不同版本的應用程序。
開發文檔的使用
Xcode帶有文檔瀏覽器,包括了類參考,API參考等。
訪問蘋果開發者官網(http://developer.apple.com/iPhone/),裡面有示例源代碼,技術指導文檔,參考文檔,視頻指導等等豐富的資源。
Objective-C語言是為支持面向對象編程而設計的一個簡單的計算機語言
Objective-C是標準的ANSI C的一個小而強大的擴展集
Objective-C對C的擴展都是基於Smalltalk語言
Objective-C給了C完全的面向對象編程能力。
Objective-C的編譯器基於gcc編譯器。
Objective-C語法是GNU C/C++語法的超集,
Objective-C編譯器能夠編譯C(.c),C++(.mm)以及Objective-C(.m)的源代碼。
Objective-C 類
一個類由兩部分組成:
介面(Interface),聲明方法,變數,指出父類和遵守的協議。文件後綴.h;
實現(Implementation),實現類,主要包括方法的實現。文件後綴.m
Objective-C 類的聲明
類的聲明的基本格式:
@interface ClassName : ItsSuperclass
{
instance variable declarations //實例變數聲明
}
method declarations //方法聲明
@end
比如:
@interface Rectangle:NSObject
{
BOOL filled; NSColor *fillColor;
@private:
float width; float height;
}
+ alloc; //類方法,[Rectangle alloc]
- (void)display; //實例方法 [rectangle display]
- (float)width; //存取器方法,和變數同名,獲取變數
- (void)setWidth:(float)inWidth; //set+變數名,設置變數值
- (void)setWidth:(float)inWidth height:(float)inHeight;
@end
Objective-C 編譯器對Objective-C源代碼(.m)進行編譯,要求方法返回值類型和參數類型都要用括弧括起來。
-(void)setWidth:(float)width height:(float)height;
多參數方法,有必要表明各個參數的功能
Objective-C 頭文件導入
#import "ItsSuperclass.h」
@interface ClassName : ItsSuperclass
{
instance variable declarations
}
method declarations
@end
#import關鍵字導入一個類的聲明,和C++中#include功能一樣
區別於#include,可以保證同一個類的聲明只被導入一次
Objective-C 類名的引用
#import "ItsSuperclass.h」
@class Rectangle;
@interface ClassName : ItsSuperclass
{
Rectangle *rectangle;
}
@end
@class 告訴編譯器Rectangle是一個類,不需要引入它的頭文件;
@class 縮短編譯代碼,減輕編譯器負擔。
Objective-C 類的實現
_每個類的實現中必須導入相應頭文件。如
#import "ClassName.h」
@implementation ClassName
method definitions
@end