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
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]
If you do not cast the return to an int, I believe you'll see some complaining in the console.
To view a UIView's frame (CGRect struct type), you can do:
p (CGRect) [myView frame]
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!";
}
Another good read is How to set a conditional breakpoint in Xcode based on an object string property?
Log Tip
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
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.
We put this macro in the precompiled header file (MyApp-Prefix.pch) so that it gets included in all the project files.
Dumping Variables
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]
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) 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