Ответ 1
Отладка с помощью GDB
XCode дает вам отладчик GDB, поэтому, как сказал Яно в своем комментарии, вы можете использовать команды GDB, такие как po (print object), для просмотра объекта.
po myObject
po myDictionary
po myArray
Чтобы печатать примитивы, такие как int, float, вы можете использовать print
, p
и px
(для просмотра числа в шестнадцатеричном формате)
print myInt
p myInt
px myInt
Вы также можете увидеть результат выполнения команд. Например, чтобы просмотреть длину строки, которую вы могли бы сделать:
p (int) [myString length]
Если вы не вернете возврат к int, я верю, что вы увидите жалобы в консоли.
Чтобы просмотреть кадр UIView (тип структуры CGRect), вы можете:
p (CGRect) [myView frame]
Наконец, если вы переопределите метод description
для класса, вы можете настроить его отображение при записи на консоль или даже в NSLog. Если вы выполните [NSString stringWithFormat:@"My object... %@", myObj]
, будет вызван метод описания этого объекта.
- (NSString*) description
{
return @"This is the object description!";
}
Еще одно хорошее чтение - Как установить условную точку останова в Xcode на основе свойства объектной строки?
Совет журнала
Если вам нужны сообщения NSLog, но только в сборках отладки, вам может понравиться макрос DLog
, который мы используем при моей работе:
#ifdef DEBUG
#define DLog(...) NSLog(__VA_ARGS__)
#else
#define DLog(...) /* */
#endif
Он работает так же, как NSLog, за исключением того, что он составлен на сборках, отличных от DEBUG. NSLog действительно может быть хитом производительности, а также может не потребоваться распространение сообщений в ваших журналах.
Мы помещаем этот макрос в предварительно скомпилированный файл заголовка (MyApp-Prefix.pch), чтобы он включался во все файлы проекта.
Демпинговые переменные
Ваш комментарий спросил о том, как сбрасывать все переменные объекта без написания кода. Я не знаю, как это сделать. Однако вы можете попытаться использовать отражение. У меня есть реализация, которая позволит вам сделать что-то вроде:
po [someObj dump]
Вы можете создать категорию в 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