未完待續,[繼續總結]
LLDB && GDB
常用的Debug快捷鍵
功能 | 命令 |
---|---|
暫停/繼續 | cmd + ctrl + Y |
斷點失效/生效 | cmd + Y |
控制檯顯示/隱藏 | cmd + shift + Y |
游標切換到控制檯 | cmd + shift + C |
清空控制檯 | cmd + K |
step over | F6 |
step into | F7 |
step out | F8 |
技巧一:格式化輸出資料
1、封裝log函式
//swift版
func DLog<T>(message: T, file: String = #file, method: String = #function, line: Int = #line) {
#if DEBUG
print("<\((file as NSString).lastPathComponent) : \(line)>, \(method) \(message)")
#endif
}
//OC版
#ifdef DEBUG
#define DLog(fmt, ...) NSLog((@"<%s : %d> %s " fmt), [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__);
#else
#define DLog(...)
#endif
複製程式碼
2、代替NSLog,列印物件的內部屬性
技巧二:條件斷點(condition)
設定斷點觸發條件
注意:
// 正確
(BOOL)[pId isEqualToString:@"short-videopage"]
// 報錯:error: no known method '-isEqualToString:'; cast the message send to the method's return type
[pId isEqualToString:@"short-videopage"]
複製程式碼
技巧三:執行中修改變數的值(expr & call)
在除錯登入相關的bug時,非常方便,不用擔心經常輸密碼,還輸錯的尷尬
除錯UI,改變指定控制元件的顏色
技巧四:符號斷點(Add Symbolic Breakpoint)
當我們檢視一個陌生的專案的時候,我們可以先執行APP,對所有的
viewDidLoad
函式新增斷點,進而瞭解程式碼執行路徑Symbol
:符號
- c語言,
methodName
只需要寫函式名,不用寫後面的() - oc樣式,
[className methodName]
className是類名,methodName是方法名(不區分類方法和例項方法) - swift樣式,
ClassName.methodName
Module
模組篩選:可以避免不同庫中方法名或者函式名相同
Condition
觸發條件
這裡可以新增一些指定觸發條件,比如新增第一個引數(arg3)不能為nil。這裡arg4代表第2個引數,以此類推。這裡也可以呼叫方法來判斷,但必須是類方法,並且返回值必須為BOOL型別。 樣例:找出給[UIImage imageNamed:]傳nil的程式碼。這裡就需要設定Symbol為
檢視某一個函式需要新增斷點的符號填寫格式(在需要除錯的函式打上斷點,程式執行走到斷點後,從堆疊資訊中檢視相應函式的格式)[UIImage imageNamed:]
,然後Condition設定為$arg3 == nil
。這樣在執行中如果遇到傳nil就會觸發斷點。
技巧五:全域性異常斷點(Add Exception Breakpoint)
技巧六:檢視整體UI層級結構(debug view hierarchy)
如果電腦配置較低,最好使用
chisel
外掛命令pviews
技巧七:開啟殭屍模式(EXC_BAD_ACCESS)
遇到EXC_BAD_ACCESS這個錯誤,那就意味著你向一個已經釋放的物件傳送訊息。Xcode知道這個物件是什麼,所以可以讓我們知道這個物件在哪裡,以及這是什麼時候發生的。當開啟殭屍模式後,遇到EXC_BAD_ACCESS,xcode可以幫我們快速定位到出現問題的程式碼。
開啟殭屍模式:
技巧八:檢視frame的值
匯入@import UIKit
(lldb) p self.view.frame
error: property 'frame' not found on object of type 'UIView *'
error: 1 errors parsing expression
(lldb) e @import UIKit
(lldb) p self.view.frame
(CGRect) $0 = (origin = (x = 0, y = 0), size = (width = 375, height = 667))
複製程式碼
或者(CGRect)
print (CGRect)[view frame]
(CGRect) $1 = (origin = (x = 0, y = 0), size = (width = 200, height = 100))
複製程式碼
技巧九:監聽所有的點選事件(UIControl、Touch、Gesture)
方法:覆寫UIAppliaction
.h檔案
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CustomApplication : UIApplication
@end
NS_ASSUME_NONNULL_END
複製程式碼
.m檔案
#import "CustomApplication.h"
@implementation CustomApplication
-(void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
}
@end
複製程式碼
main.m檔案
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "CustomApplication.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc,
argv,
NSStringFromClass([CustomApplication class]),
NSStringFromClass([AppDelegate class]));
}
}
複製程式碼
方法執行
一次事件可能會執行三次函式:
-(void)sendEvent:(UIEvent *)event
三次的force
有區別
一次事件可能會執行兩次函式:
-(void)sendEvent:(UIEvent *)event
兩次的force
沒區別
響應者鏈條
1、如果是
UIControl
事件,整合UIResponder
控制元件(UIButton
)訊息傳遞鏈(倒序)如下圖所示
2、如果是
UIGestureRecognizer
手勢事件,整合UIResponder
控制元件(UIView
)訊息傳遞鏈(倒序)如下圖所示
3、如果
UIControl
和UIGestureRecognizer
同時存在,優先順序高
其他工具:1、Chisel
Chisel是faceBook開源的lldb除錯命令集合
安裝(具體參考)
Chisel 使用 homebrew 來安裝
brew update
brew install chisel
複製程式碼
安裝完成後,將下面的命令新增到~/.lldbinit
中,xcode啟動的時候才會載入chisel
command script import /usr/local/opt/chisel/libexec/fblldb.py
複製程式碼
常用命令
檢視幫助(lldb) help
複製程式碼
其他工具:2、Reveal
Reveal 絕對是iOS介面除錯利器。使用起來不僅比Xcode自帶流暢,而且功能更加多。由於收費,30天過後就沒怎麼用但是絕對好用。
大約有4中整合方法,詳情參加官網。其他工具:3、FLEX
FLEX是Flipboard開源的一系列在應用中除錯的工具集。FLEX以第三方庫的形式整合在應用中,使用時將類庫加到工程中,然後 通過呼叫[[FLEXManager sharedManager] showExplorer]; 就可顯示出用於除錯的工具欄進行除錯。
它提供的功能如下:
- 檢視、修改views
- 檢視任何物件的屬性
- 動態的修改屬性
- 動態的呼叫例項方法和類方法
- 檢視網路請求過程
- 新增模擬的鍵盤快捷鍵
- 檢視系統日誌
- 從堆中獲取任何物件
- 檢視沙盒中的檔案
- 檢視檔案系統中的SQLite/Realm資料庫
- 在模擬器中觸發3D touch
- 檢視你應用中所有的類
- 快速獲取常用的類,例如[UIApplication sharedApplication], the app delegate, the root view controller on the key window, and more.
- 動態的檢視NSUserDefaults裡面的值