目录
1. 程序运行流程、生命周期
2. 调试方法
NSLog
断点
普通断点
全局断点
条件断点
命令行
po
NSAssert
布局问题---设置背景色、
1. 程序运行流程、生命周期
知道程序流程可以快速找到错误地方!!!
- main.m
main函数是整个程序的入口(点击应用图标,程序启动后会调用所有类、分类的+load方法,然后调用main方法)
-》初始化了一个UIApplication应用单例对象,并设置delegate为AppDelegate。UIApplication让AppDelegate代理自己去做具体实现(这样可以防止直接去修改UIApplication,更安全)。
#import
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
// 第三个参数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函数:初始化UIApplication对象,并设置dele为AppDelegate
// A:应用加载完毕后调用(只被调用一次)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ // 如果点击通知启动的APP,launtionOptions会包含通知信息
// 1.初始化窗口,设置根视图
self.window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController=[self rootVC];
self.window.backgroundColor=[UIColor whiteColor];
[self.window makeKeyAndVisible];
// 2.初始化第三方或其他配置
[self setup];
}
// B:应用即将从前台到后台(用于:游戏降低帧率、暂停游戏)
// 比如来电话了,此时会调用applicationWillResignActive
// 将要进入非活动状态执行。在此期间,应用程序不接收消息或事件。
- (void)applicationWillResignActive:(UIApplication *)application {
}
// C:应用进入后台后调用(用于:保存状态数据、销毁定时器)
// 应用被挂起,内存紧张时会销毁应用
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
// D:应用即将进入前台时调用(用于:恢复之前保存的状态数据)
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
// E:应用进入前台后调用(处于活跃状态)
// 进入活动状态执行。在此期间,应用程序可接收消息或事件。
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
// 内存紧张时调用,在这里清除内存可以避免应用被销毁
-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{
}
// F:(由于内存紧张)应用销毁前调用(用于一些收尾工作)
- (void)applicationWillTerminate:(UIApplication *)application{
}
VC生命周期
进入页面:(H->)L->A->B->D->D1->B1
离开页面: ->C->C1
返回页面: ->B->B1
退出页面: ->C->C1
其他页面使用了vc.view :H->L->A
/*
H
调用[vc new] 或 [[vc alloc]init] 或[[UIViewController alloc]initWithNibName:@"Xib" bundle:nil]时
加载nib会调用每一个对象的awakeFromNib方法
*/
-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
//
return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
/*
H
当通过StoryBoard的segue跳转或调用[[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@""]时调用
*/
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
return [super initWithCoder:aDecoder];
}
// L:可选择性覆写-自定义self.view(一般不使用)
// -------- 用于重写Controller的根视图 --------
-(void)loadView{
// 当controller的view为nil时(第一次被显示时),会调用loadView方法加载Controller的根视图
// 会从xib、storyboard中查找并赋值给self.view,没有找到时会创建一个空的View并赋值给self.view
[super loadView];
// 当覆写了loadView方法时会调用该方法(没有xib、storyboard时可覆写该方法创建View,此时不必调用[super loadView] ,可以减少不必要的开销),当没有覆写loadView方法时,会调用默认的loadView方法(会从xib、storyboard中查找,没有找到时会创建一个空的View)
}
// A:页面加载完毕后调用
/*
只有在视图控制器将其视图载入到内存之后调用该方法。
*/
-(void)viewDidLoad{
[super viewDidLoad];
}
// B:页面即将显示在屏幕上时调用
/*
当视图将要添加到窗口中并且还不可见的时候或者上层视图移出图层后本视图变成顶级视图时调用该方法,用于执行诸如改变视图方向等的操作。实现该方法时确保调用[super viewWillAppear:animated];
*/
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
// B1:页面完全显示在屏幕上后调用
/*
当视图添加到窗口中以后或者上层视图移出图层后本视图变成顶级视图时调用,用于放置那些需要在视图显示后执行的代码。确保调用 [super viewDidAppear:animated];
*/
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
// C:页面即将消失时调用
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
// C1:页面完全消失后调用
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
// D:内存紧张时调用
-(void)didReceiveMemoryWarning{
}
// F:销毁
-(void)dealloc{
// 销毁计时器
// 移除观察者
}
/*
被调用的3种情况
// 1. 强制刷新布局后调用
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
// 2. 布局发生改变后调用。
// 3. 第一次进入页面,viewWillAppear后调用一次
*/
// D
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
}
// D1
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
}
// 当vc'view的大小发生变化时,或发生旋转时调用
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)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. 调试方法
- NSLog
#define NSLog(format, ...) printf("\n[%s] %s [第%d行] %s\n", __TIME__, __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ## __VA_ARGS__] UTF8String]);
// 打印
NSLog(@"%d",30);
- 断点
普通断点
全局断点
条件断点
- 命令行
po 参数名
bt 调用的函数栈
其他命令
查看命令帮助
help 命令
help 命令 子命令 子子命令
// 例
help break 。 help break command 。 help break command add
断点
breakpoint可简写为b
获取本文件所有断点
breakpoint list
删除具体断点(2是上述命令查到的 断点序号)
breakpoint delete 2
删除所有断点
breakpoint delete
打断点(指定内存地址)
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
打断点(指定某文件行数--不会在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
打断点(动态库中的方法名)
breakpoint set --shlib x.dylib --name setupUI
等价
breakpoint set -s x.dylib -n setupUI
打印追踪轨迹
breakpoint command add 2
breakpoint set -r setupUI
别名
为命令设置别名,使用:bfl VC.m 12
command alias bfl breakpoint set -f %1 -l %2
撤销别名命令
command unalias bfl
watchpoint
查看所有watchpoint -b简略 -f全面 -v完整
watchpoint list
某变量值的改变 后触发
watchpoint set variable a
某变量值等于某固定值 后触发
watchpoint modify -c '(a=100)'
查看值改变成100的地址
c
追踪程序的运行过程
bt
查看变量值
frame variable a
查看当前进程的状态
thread list
thread step-in
step-inst step-inst-over step-out step-over
- NSAssert 断言
// true则继续,false则异常
NSAssert(contentStr!=nil, @"Argument must be non-nil");
- 布局有问题时
=>设置背景颜色
=>点击调试框上的层级按钮(三矩形)
- 快速找到需修改的控件位置
方式1、cmd+4 搜索关键字
方式2、点击调试框上的层级按钮(三矩形),再点击控件,右上查看控件名。点击箭头跳到具体位置。