runtime——Class——属性

objc_property_t

/// An opaque type that represents an Objective-C declared property.
typedef struct objc_property *objc_property_t;

/// Defines a property attribute
typedef struct {
    const char *name;           /**< The name of the attribute */
    const char *value;          /**< The value of the attribute (usually empty) */
} objc_property_attribute_t;
OBJC_EXPORT const char *property_getName(objc_property_t property) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
OBJC_EXPORT const char *property_getAttributes(objc_property_t property) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
OBJC_EXPORT char *property_copyAttributeValue(objc_property_t property, const char *attributeName)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
OBJC_EXPORT objc_property_attribute_t *property_copyAttributeList(objc_property_t property, unsigned int *outCount)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);

objc_property_t应用

@interface FBAnimal : NSObject

@property (nonatomic, assign) int age;
@property (nonatomic, strong) UIColor *color;

@end

@implementation FBAnimal

@end
- (void)use_property
{
    objc_property_t age = class_getProperty([FBAnimal class], "age");
    objc_property_t color = class_getProperty([FBAnimal class], "color");
    NSLog(@"propertyName = %s, propertyAttr = %s", property_getName(age), property_getAttributes(age));
    NSLog(@"propertyName = %s, propertyAttr = %s", property_getName(color), property_getAttributes(color));
    
    NSLog(@"age property attr list:");
    unsigned int ageAttrCnt = 0;
    objc_property_attribute_t* ageAttrList = property_copyAttributeList(age, &ageAttrCnt);
    for(int i = 0; i < ageAttrCnt; ++i)
    {
        objc_property_attribute_t thisAttr = ageAttrList[i];
        NSLog(@"attr name = %s, attr value = %s", thisAttr.name, thisAttr.value);
    }
    free(ageAttrList);
    
    NSLog(@"color property attr list:");
    unsigned int colorAttrCnt = 0;
    objc_property_attribute_t* colorAttrList = property_copyAttributeList(color, &colorAttrCnt);
    for(int i = 0; i < colorAttrCnt; ++i)
    {
        objc_property_attribute_t thisAttr = colorAttrList[i];
        NSLog(@"attr name = %s, attr value = %s", thisAttr.name, thisAttr.value);
    }
    free(colorAttrList);
}
output:
propertyName = age, propertyAttr = Ti,N,V_age
propertyName = color, propertyAttr = T@"UIColor",&,N,V_color
age property attr list:
attr name = T, attr value = i
attr name = N, attr value = 
attr name = V, attr value = _age
color property attr list:
attr name = T, attr value = @"UIColor"
attr name = &, attr value = 
attr name = N, attr value = 
attr name = V, attr value = _color

objc_property_t总结

  • property的attribute包括property类型(T),property对应数据成员(V),property原子操作性(N表示nonatomic),property内存方式(&表示strong)

api

OBJC_EXPORT objc_property_t class_getProperty(Class cls, const char *name)
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
OBJC_EXPORT BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
OBJC_EXPORT void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);

应用

@interface FBAnimal : NSObject

@property (nonatomic, assign) int age;
@property (nonatomic, strong) UIColor *color;

@end

@interface FBAnimal ()

@property (nonatomic, assign) int food1;
@property (nonatomic, assign) int food2;

@end

@interface FBAnimal ()

@property (nonatomic, assign) int food3;

@end

@implementation FBAnimal

@end

@interface FBDog : FBAnimal

@property (nonatomic, strong) NSString *country;

@end

@implementation FBDog

@end
- (void)class_property
{
    NSLog(@"animal property list:");
    unsigned int animalPropertyCnt = 0;
    objc_property_t* animalPropertyList = class_copyPropertyList([FBAnimal class], &animalPropertyCnt);
    for(int i = 0; i < animalPropertyCnt; i++)
    {
        objc_property_t thisProperty = animalPropertyList[i];
        NSLog(@"propertyName = %s, propertyAttr = %s", property_getName(thisProperty), property_getAttributes(thisProperty));
    }
    free(animalPropertyList);
    
    NSLog(@"dog property list:");
    unsigned int dogPropertyCnt = 0;
    objc_property_t* dogPropertyList = class_copyPropertyList([FBDog class], &dogPropertyCnt);
    for(int i = 0; i < dogPropertyCnt; i++)
    {
        objc_property_t thisProperty = dogPropertyList[i];
        NSLog(@"propertyName = %s, propertyAttr = %s", property_getName(thisProperty), property_getAttributes(thisProperty));
    }
    free(dogPropertyList);
}
output:
animal property list:
propertyName = food3, propertyAttr = Ti,N,V_food3
propertyName = food1, propertyAttr = Ti,N,V_food1
propertyName = food2, propertyAttr = Ti,N,V_food2
propertyName = age, propertyAttr = Ti,N,V_age
propertyName = color, propertyAttr = T@"UIColor",&,N,V_color
dog property list:
propertyName = country, propertyAttr = T@"NSString",&,N,V_country

总结

  • 如果类中已含对应name的property(包含super_class),class_addProperty不会添加到当前类中
  • 如果类中已含对应name的property,进行替换,如果类中不含对应name的Property,class_replaceProperty等同于class_addProperty
  • class_getProperty包含super_class
  • class_copyProperty不包含super_class
  • 同一类property排列顺序:extension interface->primary class interface
  • 同一类多个extension property排列顺序:按extension interface定义顺序逆序排列,即先定义extension interface排后面,后定义extension interface排前面
  • 同一interface(primary class interface,extension interface)的property排列顺序:按property定义顺序排列,即先定义property排前面,后定义property排后面
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值