7.Runtime官方文档学习--声明属性
When the compiler encounters property declarations (see Declared Properties in The Objective-C Programming Language), it generates descriptive metadata that is associated with the enclosing class, category or protocol. You can access this metadata using functions that support looking up a property by name on a class or protocol, obtaining the type of a property as an
@encodestring, and copying a list of a property's attributes as an array of C strings. A list of declared properties is available for each class and protocol.
当编译器遇到属性声明(参阅The Objective-C Programming Language中的 Declared Properties)时,它会生成和封闭类,类别或协议相关联的描述性元数据。你可以使用支持在类或协议中通过名称查找属性,获取属性类型作为@encode()字符串,复制属性列表作为C字符串数组的函数来访问这个元数据。每个类和协议都有一个声明的属性列表。
1. 属性类型和函数
The
Propertystructure defines an opaque handle to a property
descriptor.
Property结构体定义了属性描述符的不透明句柄。
typedef struct objc_property *Property;
You can use the functions
class_copyPropertyListandprotocol_copyPropertyListto retrieve an array of the properties associated with a class (including loaded categories) and a protocol respectively:
你可以使用函数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)
You can use the
property_getAttributesfunction to discover the name and the@encodetype string of a property. For details of the encoding type strings, see Type Encodings; for details of this string, see Property Type String and Property Attribute Description Examples.
你可以使用property_getAttributes函数来查出一个属性的名称和@encode类型字符串。有关编码类型字符串的详细信息,请参考 Type Encodings;这个字符串的详细信息,请参考
Property Type String and Property Attribute Description Examples。
const char *property_getAttributes(objc_property_t property)
Putting these together, you can print a list of all the properties associated with a class using the following code:
把这些放在一起,你可以使用以下代码打印和类相关的所有属性的列表:
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));
}
2.属性类型字符串
You can use the
property_getAttributesfunction to discover the name, the@encodetype string of a property, and other attributes of the property.
你可以使用property_getAttributes函数来查找一个属性的名称,@encode类型字符串以及其他的属性。
The string starts with a
Tfollowed by the@encodetype and a comma, and finishes with aVfollowed by the name of the backing instance variable. Between these, the attributes are specified by the following descriptors, separated by commas:
该字符串以T开头,后跟@encode类型和一个逗号,以V结尾并跟着后续实例变量的名称。在这些之间,属性由以下描述符指定,以逗号分隔:
Table 7-1 Declared property type encodings
| Code | Meaning |
|---|---|
| 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. |
更多示例请参考 Property Attribute Description Examples。
3.属性的属性描述符示例
有以下定义:
enum FooManChu { FOO, MAN, CHU };
struct YorkshireTeaStruct { int pot; char lady; };
typedef struct YorkshireTeaStruct YorkshireTeaStructType;
union MoneyUnion { float alone; double down; };
下表展示了property_getAttributes返回的属性描述符和对应字符串的示例:
| Property declaration | Property 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 |