声明属性
当编译器遇到属性声明(see Declared Properties in The Objective-C Programming Language)时,编译器产生以类、分类、协议进行封装的描述性元数据。你能够使用函数来获取这个元数据,该函数通过类名或者协议名来支持查看一个类,从而以@encode字符串的形式来获取属性类型,以C字符串数组的形式获取属性描述列表,声明属性的列表是用于每个类和协议。
属性类型及功能
属性结构体定义了一个不透明的属性描述
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得到一个引用,通过一个给定的类名和给定协议分别:
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 字符串的编码类型
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_getAttributes函数获取一个属性的名称和以@encode 类型的编码,和属性的其他描述。这个字符串以"T"跟随@encode类型开始, 并且以"V"跟随返回实例变量名字为结尾。在这两者之间,指定了一下描述,通过“,”分割:
表7-1 声明属性编码类型
Code | 意义 |
---|---|
R | The property is read-only (readonly) |
C | The property is a copy of the value last assigned (copy). |
& | The property is a reference to the value last assigned (retain). |
N | The property is non-atomic (nonatomic). |
G<name> | The property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,). |
S<name> | The property defines a custom setter selector name. The name follows the S (for example, ScustomSetter:,). |
D | The property is dynamic (@dynamic). |
W | The property is a weak reference (__weak). |
P | The property is eligible for garbage collection. |
t<encoding> | Specifies the type using old-style encoding. |
属性描述
提供这些描述
enum FooManChu { FOO, MAN, CHU };
struct YorkshireTeaStruct { int pot; char lady; };
typedef struct YorkshireTeaStruct YorkshireTeaStructType;
union MoneyUnion { float alone; double down; };
下边表格展示了属性描述样例和通过property_getAttributes返回的相应的字符串
属性声明 | 属性描述 |
---|---|
@property char charDefault; | Tc,VcharDefault |
@property double doubleDefault; | Td,VdoubleDefault |
@property enum FooManChu enumDefault; | Ti,VenumDefault |
@property float floatDefault; | Tf,VfloatDefault |
@property int intDefault; | Ti,VintDefault |
@property long longDefault; | Tl,VlongDefault |
@property short shortDefault; | Ts,VshortDefault |
@property struct YorkshireTeaStruct structDefault; | T{YorkshireTeaStruct="pot"i"lady"c},VstructDefault |
@property YorkshireTeaStructType typedefDefault; | T{YorkshireTeaStruct="pot"i"lady"c},VtypedefDefault |
@property union MoneyUnion unionDefault; | T(MoneyUnion="alone"f"down"d),VunionDefault |
@property unsigned unsignedDefault; | TI,VunsignedDefault |
@property int (*functionPointerDefault)(char *); | T^?,VfunctionPointerDefault |
@property id idDefault; | T@,VidDefault |
@property int *intPointer; | T^i,VintPointer |
@property void *voidPointerDefault; | T^v,VvoidPointerDefault |
@property int intSynthEquals; | Ti,V_intSynthEquals |
@property(getter=intGetFoo, setter=intSetFoo:) int intSetterGetter; | Ti,GintGetFoo,SintSetFoo:,VintSetterGetter |
@property(readonly) int intReadonly; | Ti,R,VintReadonly |
@property(getter=isIntReadOnlyGetter, readonly) int intReadonlyGetter; | Ti,R,GisIntReadOnlyGetter |
@property(readwrite) int intReadwrite; | Ti,VintReadwrite |
@property(retain) id idRetain; | T@,&,VidRetain |
@property(copy) id idCopy; | T@,C,VidCopy |
@property(nonatomic) int intNonatomic; | Ti,VintNonatomic |
@property(nonatomic, readonly, copy) id idReadonlyCopyNonatomic; | T@,R,C,VidReadonlyCopyNonatomic |
@property(nonatomic, readonly, retain) id idReadonlyRetainNonatomic; | T@,R,&,VidReadonlyRetainNonatomic |