Objective-C Xcode4中的调试提示? [英] Objective-C Debugging tips in Xcode4?
问题描述
从Flex-Flash IDE开始,我可以在代码中设置断点,并在运行时查看相应窗口中的变量值。
Coming from a Flex-Flash IDE, I was able to set breakpoints in my code and at runtime view the values of my variables in the corresponding window.
现在,我想出在哪里可以找到Xcode中的'变量'窗口,我可以看到我所有的变量,但是这些变量的值不能被看到。我所有的是数据类型和一堆十六进制数(指针?)。
Now, I figured out where I can find the 'variables' window in Xcode and I can see all my variables there BUT the values of those variables can't be seen. All I have is the data type and a bunch of hex numbers (pointers?).
我应该如何调试我的代码?我在哪里可以看到我的变量的值,而不必在代码中登录?
How am I supposed to debug my code? Where can I see the values of my variables without having to log them in my code?
我试图看到一个 NSDictionary
与一堆键/值对。而且还有任何其他 NSObject
。我读了一些关于覆盖描述方法的东西,但是本地对象呢?
I am trying to see the values of a NSDictionary
with a bunch of key/value pairs. But also any other NSObject
for that matter. I have read something about overriding the description method but what about native objects?
推荐答案
使用GDB进行调试
XCode给你一个GDB Debugger,所以就像Jano在他的评论中说的那样,你可以使用像po(print object)这样的GDB命令查看一个对象。
Debugging with GDB
XCode gives you a GDB Debugger, so like Jano said in his comment, you can use GDB commands like po (print object) to view an object.
po myObject
po myDictionary
po myArray
要打印像int,float这样的基元可以使用 print
, p
和 px
(查看十六进制数)
To print primitives like int, float, you can use print
, p
, and px
(to view the number in hex)
print myInt
p myInt
px myInt
您还可以看到运行命令的结果。例如,要查看可以执行的字符串长度:
You can also see the result of running commands. For example, to view a string length you could do:
p (int) [myString length]
如果您没有将返回值转换为int,我相信您会在控制台中看到一些抱怨。
If you do not cast the return to an int, I believe you'll see some complaining in the console.
要查看UIView的框架(CGRect结构类型),您可以执行以下操作:
To view a UIView's frame (CGRect struct type), you can do:
p (CGRect) [myView frame]
最后,如果您覆盖描述
方法,您可以自定义在写入控制台时甚至是NSLog的显示方式。如果你做了 [NSString stringWithFormat:@我的对象...%@,myObj]
该对象的描述方法将被调用。
Lastly, if you override the description
method of a class, you can customize how it displays when written to the console or even to an NSLog for that matter. If you do [NSString stringWithFormat:@"My object... %@", myObj]
the description method of that object will be called.
- (NSString*) description
{
return @"This is the object description!";
}
另一个好的阅读是如何根据对象字符串属性在Xcode中设置条件断点?
如果您想要NSLog消息,但只能在调试版本中,您可能希望 DLog
我们在我的工作中使用:
If you want NSLog messages but only in debug builds, you might like the DLog
macro we use at my work:
#ifdef DEBUG
#define DLog(...) NSLog(__VA_ARGS__)
#else
#define DLog(...) /* */
#endif
它的工作原理就像NSLog一样,除了它在非DEBUG构建之外编译。 NSLog实际上可能是一个性能指标,加上您可能不希望某些消息在您的日志中溢出。
It works just like NSLog except that it is compiled out on non-DEBUG builds. NSLog can actually be a performance hit, plus you may not want some messages spilling out in your logs.
我们将这个宏放在预编译头文件(MyApp-Prefix.pch)中,以便它被包含在所有项目文件中。
We put this macro in the precompiled header file (MyApp-Prefix.pch) so that it gets included in all the project files.
您的评论询问如何在不编写代码的情况下转储对象的所有变量。我知道没有内在的方法来做到这一点。但是,您可以尝试使用反射。我有一个实现,可以让你做一些像:
Your comment asked about how to dump all variables of an object without writing code. I know of no built in way to do this. However, you might try using reflection. I have an implementation that will allow you to do something like:
po [someObj dump]
您可以在NSObject上创建一个类别,以将所有NSObject类型的方法添加到将要转储的信息。我从目标C内省/反思借来的代码开始了代码,但是添加代码以包含属性值。
You can make a category on NSObject to add a method to all NSObject types that will dump the information you're after. I borrowed code from Objective C Introspection/Reflection to start off the code, but added code to include property values.
NSObject(DebuggingAid)类别:
NSObject (DebuggingAid) category:
#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
这篇关于Objective-C Xcode4中的调试提示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!