Jov*_*van 16 debugging macos objective-c ios xcode4
来自Flex-Flash IDE,我能够在我的代码中设置断点,并在运行时查看相应窗口中变量的值.
现在,我想出了我可以在Xcode中找到"变量"窗口的位置,我可以在那里看到所有变量但是这些变量的值无法看到.我只有数据类型和一堆十六进制数字(指针?).
我该怎么调试我的代码?我在哪里可以看到我的变量的值而无需在我的代码中记录它们?
我试图NSDictionary用一堆键/值对来查看a的值.但也是其他任何NSObject事情.我已经阅读了一些有关覆盖描述方法的内容但是本机对象呢?
Sam*_*Sam 39
XCode为您提供了一个GDB调试器,就像Jano在他的评论中所说,您可以使用像po(打印对象)这样的GDB命令来查看对象.
po myObject
po myDictionary
po myArray
Run Code Online (Sandbox Code Playgroud)
要打印喜欢整数,浮点元,就可以使用print,p以及px(查看以十六进制)
print myInt
p myInt
px myInt
Run Code Online (Sandbox Code Playgroud)
您还可以查看运行命令的结果.例如,要查看字符串长度,您可以执行以下操作:
p (int) [myString length]
Run Code Online (Sandbox Code Playgroud)
如果你没有将返回值转换为int,我相信你会在控制台中看到一些抱怨.
要查看UIView的框架(CGRect结构类型),您可以执行以下操作:
p (CGRect) [myView frame]
Run Code Online (Sandbox Code Playgroud)
最后,如果覆盖description类的方法,则可以自定义在写入控制台或甚至NSLog时的显示方式.如果你这样做[NSString stringWithFormat:@"My object... %@", myObj],将调用该对象的描述方法.
- (NSString*) description
{
return @"This is the object description!";
}
Run Code Online (Sandbox Code Playgroud)
另一个好的读物是如何根据对象字符串属性在Xcode中设置条件断点?
如果您想要NSLog消息但仅在调试版本中,您可能会喜欢DLog我在工作中使用的宏:
#ifdef DEBUG
#define DLog(...) NSLog(__VA_ARGS__)
#else
#define DLog(...) /* */
#endif
Run Code Online (Sandbox Code Playgroud)
它的工作方式与NSLog类似,不同之处在于它是在非DEBUG构建版本上编译的.NSLog实际上可能会受到性能影响,而且您可能不希望某些消息在您的日志中溢出.
我们将此宏放在预编译的头文件(MyApp-Prefix.pch)中,以便它包含在所有项目文件中.
您的评论询问如何在不编写代码的情况下转储对象的所有变量.我知道没有内置的方法来做到这一点.但是,您可以尝试使用反射.我有一个实现,可以让你做类似的事情:
po [someObj dump]
Run Code Online (Sandbox Code Playgroud)
您可以在NSObject上创建一个类别,以便为所有NSObject类型添加一个方法,该方法将转储您之后的信息.我借用Objective C Introspection/Reflection中的代码来启动代码,但添加了包含属性值的代码.
NSObject(DebuggingAid)类别:
#import <objc/runtime.h>
@interface NSObject (DebuggingAid)
- (NSString*)dump;
@end
@implementation NSObject (DebuggingAid)
- (NSString*)dump
{
if ([self isKindOfClass:[NSNumber class]] ||
[self isKindOfClass:[NSString class]] ||
[self isKindOfClass:[NSValue class]])
{
return [NSString stringWithFormat:@"%@", self];
}
Class class = [self class];
u_int count;
Ivar* ivars = class_copyIvarList(class, &count);
NSMutableDictionary* ivarDictionary = [NSMutableDictionary dictionaryWithCapacity:count];
for (int i = 0; i < count ; i++)
{
const char* ivarName = ivar_getName(ivars[i]);
NSString *ivarStr = [NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding];
id obj = [self valueForKey:ivarStr];
if (obj == nil)
{
obj = [NSNull null];
}
[ivarDictionary setObject:obj forKey:ivarStr];
}
free(ivars);
objc_property_t* properties = class_copyPropertyList(class, &count);
NSMutableDictionary* propertyDictionary = [NSMutableDictionary dictionaryWithCapacity:count];
for (int i = 0; i < count ; i++)
{
const char* propertyName = property_getName(properties[i]);
NSString *propertyStr = [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding];
id obj = [self valueForKey:propertyStr];
if (obj == nil)
{
obj = [NSNull null];
}
[propertyDictionary setObject:obj forKey:propertyStr];
}
free(properties);
NSDictionary* classDump = [NSDictionary dictionaryWithObjectsAndKeys:
ivarDictionary, @"ivars",
propertyDictionary, @"properties",
nil];
NSString *dumpStr = [NSString stringWithFormat:@"%@", classDump];
return dumpStr;
}
@end
Run Code Online (Sandbox Code Playgroud)
假设您已设置断点并且程序已停止,您将在调试区域左侧的变量视图中看到变量列表.每个都有一个值.如果它是一个原始类型,那么没有什么可看的,但如果它是一个对象,你得到的只是地址和披露箭头.公开箭头将显示对象的所有实例变量.通过这种方式,您可以深入了解您正在寻找的任何内容.
很多时候你有对象公开一个属性的getter但是没有显式存储或者以另一种形式存储它.调试器不够智能,无法遵循这些,但您可以在右侧的GDB窗口中评估所需的任何Objective-C表达式,包括执行方法调用.在我看来,最有用的命令是'p'来打印原始对象,'po'来打印对象类型的描述.
在基础类型中,变量视图窗口看起来足够聪明,能够列出NSArray的内容,但不够聪明,无法为您提供有关字典的任何有意义的内容.你被告知例如'1键/值对',但仅此而已.所以你被困在右边的窗口,输入'po dictionary'来查看内容.
我个人认为Xcode中的图形状态检查非常弱; 我发现调试器完全有效,并且可以轻松跟踪我的代码并发现错误,因为我已经学会使用右侧的控制台窗口.