Objective-C 运行时编程指南 之 Declared Properties

当编译器遇到属性声明时(参见《The Objective-C Programming Language》中的《Declared Properties》),它会产生与封闭类、类别或协议相关联的描述性元数据。你可以使用方法访问该元数据,支持通过类或协议中的名字查找属性,获得以 @encode 字符串表示的属性类型,以及拷贝属性的标志列表作为C字符串数组。已声明的属性的列表对于每个类和协议都是可用的。

7.1 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_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类型字符串属性。编码类型字符串的详情,参见 Type Encodings;这个字符串的详情,见 Property Type StringProperty Attribute Description Examples

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));
}

7.2 Property Type String 属性类型字符串

你可以使用 property_getAttributes 函数发现属性的名称、 @encode 类型字符串以及属性的其他特征。

该字符串以跟着 @encode 类型和逗号的 T 开头,最后以跟着后台实例变量的名称的 V 结束。在它们之间,属性由以下描述符说明,以逗号分隔:

Table 7-1 Declared property type encodings

CodeMeaning
RThe property is read-only (readonly).
CThe property is a copy of the value last assigned (copy).
&The property is a reference to the value last assigned (retain).
NThe property is non-atomic (nonatomic).
GThe property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,).
SThe property defines a custom setter selector name. The name follows the S (for example, ScustomSetter:,).
DThe property is dynamic (@dynamic).
WThe property is a weak reference (__weak).
PThe property is eligible for garbage collection.
tSpecifies the type using old-style encoding.

例子参见《Property Attribute Description Examples》。

7.3 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 方法的响应字符串:

Property declarationProperty description
@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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值