gpt4 book ai didi

objective-c - 打印ivar值的通用Objective-C描述方法

转载 作者:太空狗 更新时间:2023-10-30 03:28:33 25 4
gpt4 key购买 nike

在 Objective-C 中,通常使用打印对象 ID 和实例变量名称/值的方法来覆盖 -description。我想制作一个通用的 -description 方法,它通过内省(introspection)来执行此操作,而不是为每个类手动执行此操作。我希望输出类似于:

<ClassName: 0x??????, ivar1: value1, ivar2: value2, ivar3: value3, ...>

按实例变量名排序也很好(所以它们总是以相同的顺序)。最后,如果可以将其放入一个安全覆盖 NSObject 功能的类别中,那将是完美的(但我认为这并不简单,因为 NSObject.m 有一个关于在 -description 中使用 -[NSString stringWithFormat:]

最佳答案

这是一个很好的问题!因为我还没有找到这样的东西,所以我写了一个小函数来为你做这件事。它使用 method swizzling 替换了 - (NSString *)descriptionNSObject(是的,我就是这么邪恶。MAHAHAHAHAHahahahaha)并按照它们在类(您可以轻松编辑它以按字母顺序显示它们)。

不要!忘记调用 NSObjectSwizzleDescription()!

.h文件:

@interface NSObject (JSObjectAdditions)
@end


void NSObjectSwizzleDescription();

.m文件:

#import <objc/objc.h>
#import "JSObject.h"

@implementation NSObject (JSObjectAdditions)

- (NSString *)verboseDescription
{
NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: %p>", NSStringFromClass([self class]), self];

uint32_t ivarCount;
Ivar *ivars = class_copyIvarList([self class], &ivarCount);

if(ivars)
{
[description appendString:@"\n{"];

for(uint32_t i=0; i<ivarCount; i++)
{
Ivar ivar = ivars[i];
const char *ivarType = ivar_getTypeEncoding(ivar);
id ivarObject = object_getIvar(self, ivar);

[description appendFormat:@"\n %s: ", ivar_getName(ivar)];

// Default signed data types
if(strcmp(ivarType, "c") == 0)
{
char character = (char)ivarObject;
[description appendFormat:@"'%c'", character];
}
else if(strcmp(ivarType, "i") == 0 || strcmp(ivarType, "l") == 0) // l is also 32 bit in the 64 bit runtime environment
{
int integer = (int)ivarObject;
[description appendFormat:@"%i", integer];
}
else if(strcmp(ivarType, "s") == 0)
{
short shortVal = (short)ivarObject;
[description appendFormat:@"%i", (int)shortVal];
}
else if(strcmp(ivarType, "q") == 0)
{
long long longVal = (long long)ivarObject;
[description appendFormat:@"%l", longVal];
}
// Default unsigned data types
else if(strcmp(ivarType, "C") == 0)
{
unsigned char chracter = (unsigned char)ivarObject;
[description appendFormat:@"'%c'", chracter];
}
else if(strcmp(ivarType, "I") == 0 || strcmp(ivarType, "L") == 0)
{
unsigned int integer = (unsigned int)ivarObject;
[description appendFormat:@"%u", integer];
}
else if(strcmp(ivarType, "S") == 0)
{
unsigned short shortVal = (unsigned short)ivarObject;
[description appendFormat:@"%i", (int)shortVal];
}
else if(strcmp(ivarType, "Q") == 0)
{
unsigned long long longVal = (unsigned long long)ivarObject;
[description appendFormat:@"%ll", longVal];
}
// Floats'n'stuff
else if(strcmp(ivarType, "f") == 0)
{
float floatVal;
memcpy(&floatVal, &ivarObject, sizeof(float));

[description appendFormat:@"%f", floatVal];
}
else if(strcmp(ivarType, "d") == 0)
{
double doubleVal;
memcpy(&doubleVal, &ivarObject, sizeof(double));

[description appendFormat:@"%f", doubleVal];
}
// Boolean and pointer
else if(strcmp(ivarType, "B") == 0)
{
BOOL booleanVal = (BOOL)ivarObject;
[description appendFormat:@"%@", (booleanVal ? @"YES" : @"NO")];
}
else if(strcmp(ivarType, "v") == 0)
{
void *pointer = (void *)ivarObject;
[description appendFormat:@"%p", pointer];
}
else if(strcmp(ivarType, "*") == 0 || strcmp(ivarType, ":") == 0) // SEL is just a typecast for a cstring
{
char *cstring = (char *)ivarObject;
[description appendFormat:@"\"%s\"", cstring];
}
else if(strncmp(ivarType, "@", 1) == 0)
{
[description appendFormat:@"%@", ivarObject];
}
else if(strcmp(ivarType, "#") == 0)
{
Class objcClass = (Class)ivarObject;
[description appendFormat:@"%s", class_getName(objcClass)];
}
else
[description appendString:@"???"];
}

[description appendString:@"\n}"];
free(ivars);
}

return description;
}

@end


void NSObjectSwizzleDescription()
{
Method origMethod = class_getInstanceMethod([NSObject class], @selector(description));
Method newMethod = class_getInstanceMethod([NSObject class], @selector(verboseDescription));

method_exchangeImplementations(origMethod, newMethod);
}

关于objective-c - 打印ivar值的通用Objective-C描述方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6376344/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com