目錄
1. 程序運行流程、生命周期
2. 調(diào)試方法
NSLog
斷點
普通斷點
全局?jǐn)帱c
條件斷點
命令行
po
NSAssert
布局問題---設(shè)置背景色、
1. 程序運行流程、生命周期
知道程序的運行流程可以快速找到出錯的地方。
- main.m
main函數(shù)是整個程序的入口(點擊應(yīng)用圖標(biāo),程序啟動后會調(diào)用所有類、分類的+load方法,然后調(diào)用main方法)
-》初始化了一個UIApplication應(yīng)用單例對象,并設(shè)置delegate為AppDelegate。UIApplication讓AppDelegate代理自己去做具體實現(xiàn)(這樣可以防止直接去修改UIApplication,更安全)。
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
// 第三個參數(shù)nil 等價于 NSStringFromClass([UIApplication class])
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
- 生命周期
App生命周期
程序啟動:X->A—>E
Home: —>B—>C
再回來: —>D—>E
退出: —>B—>C—>F
// X
main函數(shù):初始化UIApplication對象,并設(shè)置dele為AppDelegate
// @property (nonatomic,strong) UIWindow *window;
// A:應(yīng)用加載完畢后調(diào)用(只被調(diào)用一次)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ // 如果點擊通知啟動的APP,launtionOptions會包含通知信息
// 1.初始化窗口,設(shè)置根視圖
self.window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController=[self rootVC];
self.window.backgroundColor=[UIColor whiteColor];
[self.window makeKeyAndVisible];
// 2.初始化第三方或其他配置
[self setup];
return YES;
}
// B:應(yīng)用即將從前臺到后臺(用于:游戲降低幀率、暫停游戲)
// 比如來電話了,此時會調(diào)用applicationWillResignActive
// 將要進入非活躍狀態(tài)執(zhí)行。在此期間,應(yīng)用程序不接收消息或事件。
- (void)applicationWillResignActive:(UIApplication *)application {
}
// C:應(yīng)用進入后臺后調(diào)用(用于:保存狀態(tài)數(shù)據(jù)、銷毀定時器)
// 應(yīng)用被掛起,內(nèi)存緊張時會銷毀應(yīng)用
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
// D:應(yīng)用即將進入前臺時調(diào)用(用于:恢復(fù)之前保存的狀態(tài)數(shù)據(jù))
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
// E:應(yīng)用進入前臺后調(diào)用(處于活躍狀態(tài))
// 進入活動狀態(tài)執(zhí)行。在此期間,應(yīng)用程序可接收消息或事件。
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
// 內(nèi)存緊張時調(diào)用,在這里清除內(nèi)存可以避免應(yīng)用被銷毀
-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{
}
// F:(由于內(nèi)存緊張)應(yīng)用銷毀前調(diào)用(用于一些收尾工作)
- (void)applicationWillTerminate:(UIApplication *)application{
}
VC生命周期
進入頁面:(H->)L->A->B->D->D1->B1
離開頁面: ->C->C1
返回頁面: ->B->B1
退出頁面: ->C->C1
其他頁面使用了vc.view :H->L->A
/*
H
調(diào)用[vc new] 或 [[vc alloc]init] 或[[UIViewController alloc]initWithNibName:@"Xib" bundle:nil]時
加載nib會調(diào)用每一個對象的awakeFromNib方法
*/
-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
//
return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
/*
H
當(dāng)通過StoryBoard的segue跳轉(zhuǎn)或調(diào)用[[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@""]時調(diào)用
*/
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
return [super initWithCoder:aDecoder];
}
// L:可選擇性覆寫-自定義self.view(一般不使用)
// -------- 用于重寫Controller的根視圖 --------
-(void)loadView{
// 當(dāng)controller的view為nil時(第一次被顯示時或在其他控制器中第一次用到時),會調(diào)用loadView方法加載Controller的根視圖
// 會從xib、storyboard中查找并賦值給self.view,沒有找到時會創(chuàng)建一個空的View并賦值給self.view
[super loadView];
// 沒有xib、storyboard時可覆寫該方法創(chuàng)建View,此時不必調(diào)用[super loadView] ,可以減少不必要的開銷。
// 當(dāng)沒有覆寫loadView方法時,會調(diào)用默認(rèn)的loadView方法(會從xib、storyboard中查找,沒有找到時會創(chuàng)建一個空的View
}
// A:頁面加載完畢后調(diào)用
/*
只有在視圖控制器將其視圖載入到內(nèi)存之后調(diào)用該方法。
*/
-(void)viewDidLoad{
[super viewDidLoad];
}
// B:頁面即將顯示在屏幕上時調(diào)用
/*
當(dāng)視圖將要添加到窗口中并且還不可見的時候或者上層視圖移出圖層后本視圖變成頂級視圖時調(diào)用該方法,用于執(zhí)行諸如改變視圖方向等的操作。實現(xiàn)該方法時確保調(diào)用[super viewWillAppear:animated];
*/
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
// B1:頁面完全顯示在屏幕上后調(diào)用
/*
當(dāng)視圖添加到窗口中以后或者上層視圖移出圖層后本視圖變成頂級視圖時調(diào)用,用于放置那些需要在視圖顯示后執(zhí)行的代碼。確保調(diào)用 [super viewDidAppear:animated];
*/
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
// C:頁面即將消失時調(diào)用
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
// C1:頁面完全消失后調(diào)用
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
// D:內(nèi)存緊張時調(diào)用
-(void)didReceiveMemoryWarning{
}
// F:銷毀
-(void)dealloc{
// 銷毀計時器
// 移除觀察者
}
/*
被調(diào)用的3種情況
// 1. 強制刷新布局后調(diào)用
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
// 2. 布局發(fā)生改變后調(diào)用。
// 3. 第一次進入頁面,viewWillAppear后調(diào)用一次
*/
// D
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
}
// D1
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
}
// 當(dāng)vc'view的大小發(fā)生變化時,或發(fā)生旋轉(zhuǎn)時調(diào)用
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
從A頁push到B頁
[
1. A viewDidLoad
2. A viewWillAppear
3. A viewDidAppear
]
4. B viewDidLoad
5. A viewWillDisappear
6. B viewWillAppear
7. A viewDidDisappear
8. B viewDidAppear
從B頁pop會A頁
1. B viewWillDisappear
2. A viewWillAppear
3. B viewDidDisappear
4. A viewDidAppear
View生命周期
純代碼 [[UIView alloc]init] 、 [UIView new]
initWithFrame
init
layoutSubviews
純代碼 [[UIView alloc]initWithFrame:CGRectZero]
initWithFrame
layoutSubviews
xib [[[NSBundle mainBundle]loadNibNamed:@"View" owner:nil options:nil]lastObject]
initWithCoder
awakeFromNib
layoutSubviews
2. 調(diào)試方法
- NSLog
#define NSLog(format, ...) printf("\n[%s] %s [第%d行] %s\n", __TIME__, __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ## __VA_ARGS__] UTF8String]);
// 打印
NSLog(@"%d",30);
- 斷點
普通斷點

在代碼行左側(cè)單擊(快捷鍵:cmd+| )
全局?jǐn)帱c

全局?jǐn)帱c
條件斷點

條件斷點(右擊斷點)
- 命令行
po 參數(shù)名

命令行: po 參數(shù)名
bt 調(diào)用的函數(shù)棧
其他命令
查看命令幫助
help 命令
help 命令 子命令 子子命令
// 例
help break 。 help break command 。 help break command add
斷點
breakpoint可簡寫為b
獲取本文件所有斷點
breakpoint list
刪除具體斷點(2是上述命令查到的 斷點序號)
breakpoint delete 2
刪除所有斷點
breakpoint delete
打斷點(指定內(nèi)存地址)
breakpoint 0x000086bc
打斷點(指定方法名)
breakpoint set --name setupUI
等價
breakpoint set -n setupUI
breakpoint set -n "-[VC setupUI]"
br s -n "-[VC setupUI]"
打斷點(指定多個方法名)
breakpoint set --name setupUI --name setupNavBar
打斷點(指定某文件行數(shù)--不會在XCode上顯示)
breakpoint set --file VC1.m --line 26
等價
breakpoint set -f VC1.m -l 26
打斷點(指定C方法,不對OC同名方法打斷點)
breakpoint set --method setupUI
等價
breakpoint set -M setupUI
打斷點(指定OC方法,不對C同名方法打斷點)
breakpoint set --selector setupUI
等價
breakpoint set -S setupUI
打斷點(動態(tài)庫中的方法名)
breakpoint set --shlib x.dylib --name setupUI
等價
breakpoint set -s x.dylib -n setupUI
打印追蹤軌跡
breakpoint command add 2
breakpoint set -r setupUI
別名
為命令設(shè)置別名,使用:bfl VC.m 12
command alias bfl breakpoint set -f %1 -l %2
撤銷別名命令
command unalias bfl
watchpoint
查看所有watchpoint -b簡略 -f全面 -v完整
watchpoint list
某變量值的改變 后觸發(fā)
watchpoint set variable a
某變量值等于某固定值 后觸發(fā)
watchpoint modify -c '(a=100)'
查看值改變成100的地址
c
追蹤程序的運行過程
bt
查看變量值
frame variable a
查看當(dāng)前進程的狀態(tài)
thread list
thread step-in
step-inst step-inst-over step-out step-over
- NSAssert 斷言
// true則繼續(xù),false則異常
NSAssert(contentStr!=nil, @"Argument must be non-nil");
- 布局有問題時
=>設(shè)置背景顏色
=>點擊調(diào)試框上的層級按鈕(三矩形)

三矩形
- 快速找到需修改的控件位置
方式1、cmd+4 搜索關(guān)鍵字
方式2、點擊調(diào)試框上的層級按鈕(三矩形),再點擊控件,右上查看控件名。點擊箭頭跳到具體位置。