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
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.
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
This question seems the have the answer to your question.
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!
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.
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