如何dynamic确定Objective-C属性types?

我试图dynamic确定Objective-C中的属性的types。 根据我在这个网站和其他地方阅读的内容,我相信我正在做正确的事情。 但是,我的代码不起作用。

下面的代码片段演示了这个问题。 尝试获取“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 

枚举这里描述的属性也不会产生预期的结果。 以下代码:

 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 

logging的属性,如“backgroundColor”,“框架”等缺失,而包括“caretRect”和“gesturesEnabled”等未公开的属性。

任何帮助将非常感激。 如果它是相关的,我看到在iOS模拟器上的这种行为。 我不知道在实际设备上是否会发生同样的情况。

谢谢,Greg

你得到的UIView属性,问题是backgroundColor不是一个UIView属性,是一个类属性。 检查UIView.h。 我认为你不能得到一个objc_category,但看看类转储。

稍微回避一下这个问题,下面的作品:

 NSMethodSignature *signature = [[UIView class] instanceMethodSignatureForSelector:@selector(backgroundColor)]; NSLog(@"%s", [signature methodReturnType]); 

所以运行时可能会失去这样一个事实,即backgroundColor是一个属性,但是您似乎总是从第一个代码片段中的信息开始,所以它只是检查getter的返回types。

您可以find类别属性作为方法。

 @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' ... 

不要忘记尊重布尔属性的getter / setter符号,search'isHidden'而不是'隐藏'。