きれいに直接これらのインスタンス変数にアクセスする唯一の方法は、有用な機能object_getInstanceVariable
を提供するObjective-Cランタイムを介してです。値は参照渡しに渡され、さまざまな型がある可能性があります。そのため、デバッガではあまり役に立ちません。しかしあなたの質問は私に解決策を思いつくよう促しました。
NSObjectにカテゴリを書き込んで、アクセサの副作用を心配することなく、デバッガからインスタンス変数をイントロスペクトすることができます。
(lldb) po [self valueOfInstanceVariable:@"_name"]
IMG_4078.PNG
ここでは、コードです:
NSObjectの+ IvarIntrospection.h
#if DEBUG
#import <Foundation/Foundation.h>
@interface NSObject (IvarIntrospection)
- (id)valueOfInstanceVariable:(NSString *)ivarName;
@end
#endif
NSObjectの+ IvarIntrospection.m
#if DEBUG
#import "NSObject+IvarIntrospection.h"
#import <objc/runtime.h>
@implementation NSObject (IvarIntrospection)
- (id)valueOfInstanceVariable:(NSString *)ivarName {
// Get the value of the instance variable
// Use a union in order to convert the value to a float or double (see http://en.wikipedia.org/wiki/Type_punning)
union {
void *value;
float f;
double d;
} ivar;
Ivar ivarInfo = object_getInstanceVariable(self, [ivarName UTF8String], &ivar.value);
// If the instance variable doesn't exist, try adding an underscore
if (!ivarInfo && ![ivarName hasPrefix:@"_"]) {
NSString *underscoredIvarName = [@"_" stringByAppendingString:ivarName];
NSLog(@"Instance variable '%@' does not exist. Perhaps you meant '%@?' Let's try that.", ivarName, underscoredIvarName);
return [self valueOfInstanceVariable:underscoredIvarName];
// If there's already an underscore, error
} else if (!ivarInfo) {
NSLog(@"Instance variable '%@' does not exist.", ivarName);
return nil;
}
// Figure out what type the instance variable is and return a sensible representation
const char *type = ivar_getTypeEncoding(ivarInfo);
switch (type[0]) {
case 'c':
return [NSNumber numberWithChar:(char)ivar.value];
case 'i':
return [NSNumber numberWithInt:(int)ivar.value];
case 's':
return [NSNumber numberWithShort:(short)ivar.value];
case 'l':
return [NSNumber numberWithLong:(long)ivar.value];
case 'q':
return [NSNumber numberWithLongLong:(long long)ivar.value];
case 'C':
return [NSNumber numberWithUnsignedChar:(unsigned char)ivar.value];
case 'I':
return [NSNumber numberWithUnsignedInt:(unsigned int)ivar.value];
case 'S':
return [NSNumber numberWithUnsignedShort:(unsigned short)ivar.value];
case 'L':
return [NSNumber numberWithUnsignedLong:(unsigned long)ivar.value];
case 'Q':
return [NSNumber numberWithUnsignedLongLong:(unsigned long long)ivar.value];
case 'f':
return [NSNumber numberWithFloat:ivar.f];
case 'd':
return [NSNumber numberWithDouble:ivar.d];
case '*':
return [NSString stringWithUTF8String:(const char *)ivar.value];
case '@':
case '#':
return (id)ivar.value;
case ':':
return NSStringFromSelector((SEL)ivar.value);
default:
return [NSValue valueWithBytes:&ivar.value objCType:type];
}
}
@end
#endif
プロジェクトにカテゴリを追加した後、あなたはこれを行うことができます
リリース用にコンパイルすると、カテゴリは自動的に無効になります(debu gマクロ)。
OPは、デバッガで変数にアクセスする方法について質問しています。それをコンパイルする方法ではありません。私は同じ問題があります。この回答は役に立ちません。 – rrrus