当编译器遇到变量声明时,将结合类、类别或者协议生成描述性元数据,你可以通过根据属性名称获取类的或者协议的属性的函数得到一个属性用@encode字符串表示的类型,并且将属性的特性复制出来用C字符串的数组表示。任何一个类或者协议都有声明属性的数组
Property Type and Functions
Property结构体定义对属性的描述不透明
typedef struct objc_property *Property;
你可以通过函数 class_copyPropertyList 和 protocol_copyPropertyList来分别获得关联类(包括已经加载的类别)和协议的属性列表
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount)
例如,有如下的类声明
@interface Lender : NSObject {
float alone;
}
@property float alone;
@end
你可以通过下面的方式获取属性列表
id LenderClass = objc_getClass("Lender");
unsigned int outCount;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);
同时可以用property_getName函数获取属性名称
const char *property_getName(objc_property_t property)
可以用 class_getProperty 和 protocol_getProperty 根据属性名称分别获取类或者协议里面的属性引用(reference)
objc_property_t class_getProperty(Class cls, const char *name)
objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty)
你可以用 property_getAttributes 函数来找到属性的名称和用@encode字符串表示的类型。详情见下面Property Type String章节。
const char *property_getAttributes(objc_property_t property)
结合上面的几种函数。你可以打印一个类的所有属性,如下:
id LenderClass = objc_getClass("Lender");
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}
Property Type String
你可以通过property_getAttributes函数来找到属性的名称和@encode类型字符串,以及其他属性的特性
属性类型字符串以字母T开头,紧接着是@encode类型和一个逗号,最后以V加返回实例的名称结尾。在这中间,属性的特性由下面几种描述符表示,用逗号分开:
详细见下方例子
Property Attribute Description Examples
列举下面几种定义:
enum FooManChu { FOO, MAN, CHU };
struct YorkshireTeaStruct { int pot; char lady; };
typedef struct YorkshireTeaStruct YorkshireTeaStructType;
union MoneyUnion { float alone; double down; };
下表展示了例子属性声明对应着的property_getAttributes:函数返回