我正在尝试动态确定Objective-C中属性的类型。根据我在本网站和其他地方的内容,我相信我做的是正确的。但是,我的代码无效。
下面的代码段演示了这个问题。尝试获取“backgroundColor”和“frame”的属性信息(两者都是UIView的有效属性)失败(class_getProperty()返回NULL):
id type = [UIView class];
objc_property_t backgroundColorProperty = class_getProperty(type, "backgroundColor");
fprintf(stdout, "backgroundColorProperty = %d\n", (int)backgroundColorProperty); // prints 0
objc_property_t frameProperty = class_getProperty(type, "frame");
fprintf(stdout, "frameProperty = %d\n", (int)frameProperty); // prints 0
按照描述here枚举属性也不会产生预期的结果。以下代码:
NSLog(@"Properties for %@", type);
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(type, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}
生成此输出:
2012-03-09 13:18:39.108 IOSTest[2921:f803] Properties for UIView
caretRect T{CGRect={CGPoint=ff}{CGSize=ff}},R,N,G_caretRect
gesturesEnabled Tc,N
deliversTouchesForGesturesToSuperview Tc,N
skipsSubviewEnumeration Tc,N
viewTraversalMark Tc,N
viewDelegate T@"UIViewController",N,G_viewDelegate,S_setViewDelegate:
inAnimatedVCTransition Tc,N,GisInAnimatedVCTransition
monitorsSubtree Tc,N,G_monitorsSubtree,S_setMonitorsSubtree:
backgroundColorSystemColorName T@"NSString",&,N,G_backgroundColorSystemColorName,S_setBackgroundColorSystemColorName:
userInteractionEnabled Tc,N,GisUserInteractionEnabled
tag Ti,N,V_tag
layer T@"CALayer",R,N,V_layer
缺少记录的属性,例如“backgroundColor”,“frame”等,而包括“caretRect”和“gesturesEnabled”等未记录的属性。
非常感谢任何帮助。如果它是相关的,我在iOS模拟器上看到这种行为。我不知道在实际设备上是否会发生同样的事情。
谢谢, 格雷格
答案 0 :(得分:6)
您正在获取UIView属性,问题是backgroundColor不是UIView属性,是类别属性。检查UIView.h。我想你不能得到一个objc_category,但看看class-dump。
答案 1 :(得分:0)
稍微躲避这个问题,以下工作:
NSMethodSignature *signature = [[UIView class]
instanceMethodSignatureForSelector:@selector(backgroundColor)];
NSLog(@"%s", [signature methodReturnType]);
因此,运行时可能会以某种方式失去backgroundColor
属性的事实,但您似乎始终在第一个代码片段中以该信息开头,因此它只检查getter的返回类型。
答案 2 :(得分:0)
您可以找到类别属性作为方法。
@import ObjectiveC;
static void test(Class class, NSString* methodName) {
Method method = class_getInstanceMethod(class, NSSelectorFromString(methodName));
const char* type = method_copyReturnType(method);
printf("%s : %s\n", methodName.UTF8String, type);
free((void*)type);
}
然后你检查一下......
test([UILabel class], @"alpha");
test([UILabel class], @"textColor");
test([UILabel class], @"isHidden");
test([UILabel class], @"minimumScaleFactor");
在runtime.h中查看这些定义后
#define _C_ID '@'
#define _C_CLASS '#'
#define _C_SEL ':'
#define _C_CHR 'c'
#define _C_UCHR 'C'
#define _C_SHT 's'
#define _C_USHT 'S'
#define _C_INT 'i'
#define _C_UINT 'I'
...
不要忘记尊重BOOL属性的getter / setter表示法,搜索'isHidden'而不是'hidden'。