定义属性
当编译器碰到属性声明的时候,会生成和类,类别,协议相关的描述性元数据,在类和协议中,你可以通过名字来访问属性的源数据,你可以通过使用 @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 |