【译】runtime编程指南_08属性声明

定义属性

当编译器碰到属性声明的时候,会生成和类,类别,协议相关的描述性元数据,在类和协议中,你可以通过名字来访问属性的源数据,你可以通过使用 @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_getPropertyprotocol_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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容