声明的属性
当编译器遇到属性声明时(请参阅Objective-C编程语言中的声明属性),它会生成与封闭类,类别或协议相关联的描述性元数据。您可以在类或协议上按名称查找属性,将属性类型作为@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
函数来发现名称,@encode
属性的类型字符串以及属性的其他属性。
该字符串以a开头,T
后跟@encode
类型和逗号,并以a 结尾,后跟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.
有关示例,请参见属性属性描述示例。
属性属性描述示例
鉴于这些定义:
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
Last updated
Was this helpful?