美文网首页
【译】runtime编程指南_08属性声明

【译】runtime编程指南_08属性声明

作者: xiao333ma | 来源:发表于2016-09-10 15:28 被阅读58次

    定义属性

    当编译器碰到属性声明的时候,会生成和类,类别,协议相关的描述性元数据,在类和协议中,你可以通过名字来访问属性的源数据,你可以通过使用 @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 来获取属性的名字,属性的类型,属性的其他属性。

    这个字符串,以 T 开头,后边是 @encode 的类型,后边是一个逗号,在后边以 V 加上实例变量的名字结束。在这些中间,下边这些对属性描述,被用逗号分隔开。

    属性声明的编码

    Code Meaning
    R readonly
    C copy
    & retain
    N nonatomic
    G<name> 属性自定义了一个 getter 方法,方法的名字在 G 后边 例如 GcustomGetter
    S<name> 属性自定义了一个 setter 方法,方法的名字在 S 后边 例如 ScustomSetter
    D 属性是动态的,@dynamic
    W __weak 弱引用
    P 这个属性是可被垃圾回收的
    t<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 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

    相关文章

      网友评论

          本文标题:【译】runtime编程指南_08属性声明

          本文链接:https://www.haomeiwen.com/subject/adiyettx.html