返回介绍

声明的属性

发布于 2024-10-06 10:34:44 字数 15577 浏览 0 评论 0 收藏 0

当编译器遇到属性声明时(请参阅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_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函数来发现名称,@encode属性的类型字符串以及属性的其他属性。

该字符串以a开头,T后跟@encode类型和逗号,并以a 结尾,后跟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).
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:,).
DThe property is dynamic (@dynamic).
WThe property is a weak reference (__weak).
PThe 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 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文