定义属性
当编译器碰到属性声明的时候,会生成和类,类别,协议相关的描述性元数据,在类和协议中,你可以通过名字来访问属性的源数据,你可以通过使用 @encode 来获取属性的类型,把这个属性的属性复制到一个 C 的字符数组中。在每一个类和协议中,属性列表都是可用的。
属性的类型和方法
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 获得一个属性的引用,通过给定的类的名字或者属性的名字
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 来获取属性的名字,属性的类型,属性的其他属性。
这个字符串,以 T 开头,后边是 @encode 的类型,后边是一个逗号,在后边以 V 加上实例变量的名字结束。在这些中间,下边这些对属性描述,被用逗号分隔开。
属性声明的编码
| Code | Meaning |
|---|---|
| R | readonly |
| C | copy |
| & | retain |
| N | nonatomic |
| G<name> | 属性自定义了一个 getter 方法,方法的名字在 G 后边 例如 GcustomGetter
|
| S<name> | 属性自定义了一个 setter 方法,方法的名字在 S 后边 例如 ScustomSetter
|
| D | 属性是动态的,@dynamic |
| W | __weak 弱引用 |
| P | 这个属性是可被垃圾回收的 |
| t<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 signed signedDefault; | Ti,VsignedDefault |
| @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; Note: the compiler warns: "no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed" | T@,VidDefault |
| @property int *intPointer; | T^i,VintPointer |
| @property void *voidPointerDefault; | T^v,VvoidPointerDefault |
| @property int intSynthEquals; In the implementation block: @synthesize intSynthEquals=_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(assign) int intAssign; | Ti,VintAssign |
| @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 |








网友评论