大部分情况普通断点都可以满足,我们只需要单击编辑区域左侧的行号即可添加普通断点。
适用场景:
一个函数被多次调用,但只需要调试其中每一次情况。
对于一些因为异常数据导致的bug。
我们只需要右键普通断点添加条件判断即可。
p命令:查看基本数据类型的值
po命令:查看oc对象
简单查看一个变量或者OC对象的值在watch窗口完全可以满足,但是如果需要查看一个oc对象的属性,或者一个oc对象方法的返回值怎么办呢?p和po命令后面都可以接相应的表达式:
全称 expression,可以在调试时动态修改变量的值,同时打印出结果。使用 expr 命令动态修改变量的值,可以在调试的时候覆盖一些异常路径,对调试异常处理的代码很有用。
call 命令用来动态调用函数,可以在不增加代码不重新编译的情况下动态调用一个方法。
image 命令可以列出当前app中的所有模块,可以查找一个地址对应的代码位置,在调试越狱插件时,可以用image list命令查看越狱插件是否注入自己的App。当遇到crash时,查看线程栈只能看到栈帧的地址,使用 image lookup -address 地址命令可以方便的定位这个地址对应的代码行。
bt 命令可以查看线程的堆栈信息,该信息也可以在导航区的Debug Navigator看到;
bt:打印当前线程栈 bt all:打印所有线程栈
接下来练习创建一个将输入文字进行语音朗读的程序:
创建完毕后,会有以下两个文件存在于文件夹中,分别是接口区和实现区。
点击右上角的加号,可以在界面中添加按钮文本框以及方法。
每个按钮的功能都可以拖拽至 .h 文件中自动生成声明,根据自己需要进行设置。
以下是接口文件
#import <Cocoa/Cocoa.h> //声明采用Cocoa编程
NS_ASSUME_NONNULL_BEGIN
@interface SpeakLine : NSWindowController{
NSSpeechSynthesizer *_speechSynth;
}
@property (weak) IBOutlet NSTextFieldCell *textField;
- (IBAction)stopIt:(id)sender;
- (IBAction)sayIt:(id)sender;
@end
NS_ASSUME_NONNULL_END
以下是实现文件
#import "SpeakLine.h"
@interface SpeakLine ()
@end
@implementation SpeakLine
-(id) init{
self = [super init];
if(self){
//日志可帮助开发者理解程序运作,并可以找出bug
NSLog(@"init");
//创建一个NSSpeechSynthesizer的一个新实例,该实例使用默认声音
_speechSynth = [[NSSpeechSynthesizer alloc]initWithVoice:nil];
}
return self;
}
- (void)windowDidLoad {
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
- (IBAction)sayIt:(id)sender {
NSString *string = [_textField stringValue];
if([string length] == 0){
NSLog(@"字符串 %@ 长度为0",_textField);
return;
}
[_speechSynth startSpeakingString:string];
NSLog(@"你刚刚说了 %@",string);
}
- (IBAction)stopIt:(id)sender {
NSLog(@"停止");
[_speechSynth stopSpeaking];
}
@end
程序主界面
采用以上的方法,分别进行创建类,添加Object方法…
需要注意的是,新添加的Object方法需要将类调整为自定义的类名
以下是接口文件部分:
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface CountStringApp : NSWindowController
@property (weak) IBOutlet NSTextFieldCell *textFile;// 创建一个textFile对象,用来存放输入的字符串
- (IBAction)Count:(id)sender;//创建一个Count的实现,用来统计字符串的长度
@property (strong) IBOutlet NSTextFieldCell *print;//创建一个print对象,用来存放最终输出的结果
@end
NS_ASSUME_NONNULL_END
以下是实现文件部分:
#import "CountStringApp.h"
@interface CountStringApp ()
@end
@implementation CountStringApp
- (void)windowDidLoad {
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
- (IBAction)Count:(id)sender {
NSString *test = [_textFile stringValue];//创建一个字符串对象test用来保存textFile
if([test length] == 0){
test = @"字符串长度为0";//如果字符串长度为0,则将test的值赋值为 test
[_print setStringValue:test]; //使用_print调用 setStringValue:方法,将test的值赋给自身
return;
}
NSInteger res = [test length];//创建一个NSInter类的对象res,存放输入字符串的长度
NSString *result;//在创建一个字符串对象用来存放输出的结果
result = [NSString stringWithFormat:@"「%@」 的长度为:%d",test,res];
[_print setStringValue:result];
}
@end
关于 stringWithFormat:方法
//常见的输出方式:
NSString *height;
height = [NSString stringWithFormat:@"Your height is %d feet, %d inches.",5,11];
NSLog(@"%@",height);
输出结果:
2013-04-12 10:30:47.744 String[2161:303] Your height is 5 feet, 11 inches.
//输出多个字符的方式(以两个字符为例):
NSString *str;
NSString *str1 = @"123";
NSString *str2 = @"465";
str = [NSString stringWithFormat:@"%@,%@",str1, str2];
NSLog(@"%@",str);
//输出结果:
2013-04-12 10:31:48.213 String[2171:303] 123,465
以下是程序主界面: