加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

通用Objective-C描述方法来打印ivar值

发布时间:2020-12-16 03:05:49 所属栏目:百科 来源:网络整理
导读:在Objective-C中,通过打印对象ID和实例变量名称/值的方法来覆盖-description是很常见的.我想制作一个通用的描述方法,通过内省来做,而不是为每个类手动这样做.我希望输出如下: ClassName: 0x??????,ivar1: value1,ivar2: value2,ivar3: value3,... 对实例变
在Objective-C中,通过打印对象ID和实例变量名称/值的方法来覆盖-description是很常见的.我想制作一个通用的描述方法,通过内省来做,而不是为每个类手动这样做.我希望输出如下:
<ClassName: 0x??????,ivar1: value1,ivar2: value2,ivar3: value3,...>

对实例变量名进行排序也是很好的(所以它们总是按照相同的顺序排列).最后,如果这可以安全地覆盖NSObject功能,那将是完美的(但是我看到这并不简单,因为NSObject.m有一个关于在-description中使用 – [NSString stringWithFormat:]的警告).

解决方法

这是一个很好的问题!因为我没有找到这样的东西,我写了一个小功能,为你做这个.它使用方法swizzling替换(NSString *)NSObject的描述(是的,我是这个邪恶的MAHAHAHAHAHAHAHAHAHAHAHAHAHA),并按照它们也出现在类中的顺序打印出ivar(您可以轻松地编辑它们以字母顺序显示) .

别!忘了调用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","S") == 0)
            {
                unsigned short shortVal = (unsigned short)ivarObject;
                [description appendFormat:@"%i","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,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);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读