19

デバッグ目的で、クラスのプロパティのさまざまな値をすべてログにすばやく簡単に出力する方法があるかどうか疑問に思っていました。BOOL、floatなどのすべての値が何であるかを知りたいのと同じように。

4

5 に答える 5

30

この質問には、あなたの質問に対する答えがあるようです。

アップデート:

私は興味を持って、カテゴリーを作りました:

//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

あなたのクラスにそれを含めてください:#import "NSObject+logProperties.h"

そしてそれらのプロパティを呼び出し[self logProperties];ます!

于 2012-12-17T21:42:37.320 に答える
7

現在の回答は、プロパティに対してそれを行う方法を示しています。すべてのインスタンス変数を出力したい場合は、次のようなことを行うことができます。

- (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);
}

実際にこれを行うことは特にお勧めしませんが、デバッグ目的の場合は問題ありません。これをカテゴリとして実装しNSObject、デバッグ時に使用できるようにそのままにしておくことができます。すべてのタイプのエンコーディングで完了した場合、それは非常に素晴らしい小さな方法になる可能性があります。

于 2012-12-17T22:01:36.597 に答える
0

はい、1 つの方法は、すべてのプロパティを要求してから、たとえば KVC を使用することです。

//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];
}

別の方法は、クラスのすべてのメソッドを調べ、戻り値の型を取得し、それを呼び出して出力することです

于 2012-12-17T21:42:53.673 に答える
-2

手っ取り早いのはオーバーライドすることdebugDescriptionです:

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

もちろん、オブジェクトが複雑な場合、これには時間がかかる可能性があります。

于 2012-12-17T21:46:47.430 に答える