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排后面