[OC Runtime编程指南_翻译]八、声明属性

[OC Runtime编程指南_翻译]一、介绍 & 二、运行时版本和平台
[OC Runtime编程指南_翻译]三、与运行时交互
[OC Runtime编程指南_翻译]四、消息传递
[OC Runtime编程指南_翻译]五、动态方法解析
[OC Runtime编程指南_翻译]六、消息转发
[OC Runtime编程指南_翻译]七、类型编码
[OC Runtime编程指南_翻译]八、声明属性

注:pdf翻译文档百度云下载链接,密码:zcs2

当编译器遇到属性声明(请参阅 _Objective-C _编程语言声明属性)时,它会生成与封闭类、类别或协议相关联的描述性元数据。您可以使用支持在类或协议上按名称查找属性、以**@encode**字符串形式获取属性类型以及以C字符串数组形式复制属性属性列表的函数来访问此元数据。声明的属性列表可用于每个类和协议

属性类型和功能

**Property**结构定义属性描述符的不透明句柄。

typedef struct objc_property *Property;

可以使用函数**class_copyPropertyListprotocol_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字符串。有关编码类型字符串的详细信息,请参阅 类型编码;有关此字符串的详细信息,请参阅 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));

}

属性类型字符串

可以使用**property_getAttributes函数来发现属性的名称、@encode** type字符串以及属性的其他属性。

字符串以**T开头,后跟@encode类型和逗号,以V**结尾,后跟支持实例变量的名称。其中,属性由以下描述符指定,用逗号分隔:

Table 7-1 声明的属性类型编码

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 The property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,).
S 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 Specifies the type using old-style encoding.

示例, 请参见 Property Attribute Description Examples.

Property Attribute 描述示例

根据这些定义:

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

猜你喜欢

转载自blog.csdn.net/lin1109221208/article/details/108395387