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

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!


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


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.