Is there a way to log all the property values of an Objective-C instance

前端 未结 5 1651
庸人自扰
庸人自扰 2021-02-04 03:22

I was just wondering if there is a quick and easy way of printing out to the log all of the various values of the properties to my class for debugging purposes. Like I would lik

相关标签:
5条回答
  • 2021-02-04 03:30

    The current answers just show how to do it for properties. If you want every instance variable printed out you could do something like the below.

    - (void)logAllProperties {
        unsigned int count;
        Ivar *ivars = class_copyIvarList([self class], &count);
        for (unsigned int i = 0; i < count; i++) {
            Ivar ivar = ivars[i];
    
            const char *name = ivar_getName(ivar);
            const char *type = ivar_getTypeEncoding(ivar);
            ptrdiff_t offset = ivar_getOffset(ivar);
    
            if (strncmp(type, "i", 1) == 0) {
                int intValue = *(int*)((uintptr_t)self + offset);
                NSLog(@"%s = %i", name, intValue);
            } else if (strncmp(type, "f", 1) == 0) {
                float floatValue = *(float*)((uintptr_t)self + offset);
                NSLog(@"%s = %f", name, floatValue);
            } else if (strncmp(type, "@", 1) == 0) {
                id value = object_getIvar(self, ivar);
                NSLog(@"%s = %@", name, value);
            }
            // And the rest for other type encodings
        }
        free(ivars);
    }
    

    Although I wouldn't particularly suggest doing this in practice, but if it's for debug purposes then that's fine. You could implement this as a category on NSObject and keep it lying around for use when debugging. If completed for all type encodings then it could make for a very nice little method.

    0 讨论(0)
  • 2021-02-04 03:42

    yes, one way would be to ask for all properties and then use KVC for example:

    //properties
    unsigned int cProperties = 0;
    objc_property_t *props = class_copyPropertyList(self.class, &cProperties);
    for(int i = 0; i < cProperties; i++) {
        const char *name = property_getName(props[i]);
        NSLog(@"%@=%@", name, [self valueForKey:name];
    }
    

    an alternate way is to go through all the methods of a class, get the return type, invoke and print it

    0 讨论(0)
  • 2021-02-04 03:45

    This question seems the have the answer to your question.

    Update:

    I got curious and made a catagory:

    //Using Xcode 4.5.2 - iOS 6 - LLDB - Automatic Reference Counting
    
    //NSObject+logProperties.h    
    @interface NSObject (logProperties)
    - (void) logProperties;
    @end
    
    //NSObject+logProperties.m
    #import "NSObject+logProperties.h"
    #import <objc/runtime.h>
    
    @implementation NSObject (logProperties)
    
    - (void) logProperties {
    
        NSLog(@"----------------------------------------------- Properties for object %@", self);
    
        @autoreleasepool {
            unsigned int numberOfProperties = 0;
            objc_property_t *propertyArray = class_copyPropertyList([self class], &numberOfProperties);
            for (NSUInteger i = 0; i < numberOfProperties; i++) {
                objc_property_t property = propertyArray[i];
                NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)];
                NSLog(@"Property %@ Value: %@", name, [self valueForKey:name]);
            }
            free(propertyArray);
        }    
        NSLog(@"-----------------------------------------------");
    }
    
    @end
    

    Include it in your class: #import "NSObject+logProperties.h"

    and call [self logProperties]; to those properties!

    0 讨论(0)
  • 2021-02-04 03:47

    The quick and dirty would be to override debugDescription:

    -(NSString*)debugDescription {
        NSString *str = [[NSString alloc] initWithFormat:@"My BOOL 1: %d, My Float: %f", self.myBool, self.myFoat];
        return str;
    }
    

    Of course, if your object is complex, this could be time consuming.

    0 讨论(0)
  • 2021-02-04 03:51

    There are now these methods on NSObject :

    @interface NSObject (Private)
    -(id)_ivarDescription;
    -(id)_shortMethodDescription;
    -(id)_methodDescription;
    @end
    

    In swift:

    myObject.perform("_ivarDescription")
    

    Thanks to this article

    0 讨论(0)
提交回复
热议问题