/**
cls:指定获取的是哪个类的属性描述信息数组,即objc_property_t类型数组
outCount:输出指针,指明返回objc_property_t类型数组的大小
返回objc_property_t类型的数组,每个objc_property_t元素描述一个属性的信息,这个数组中不会包括超类的属性
objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount )
property:指定属性描述信息
返回属性描述信息中的属性名称的c字符串
const char * property_getName ( objc_property_t property )
property:指定属性描述信息
返回属性描述信息中所有特性的c字符串(固定格式,以逗号隔开,通常是T@"类型"开头,V_属性名称结尾的格式),类似于NSObject的description方法返回值
const char * property_getAttributes ( objc_property_t property );
property:指定属性描述信息
outCount:输出指针,指明返回objc_property_attribute_t类型数组的大小
返回objc_property_attribute_t类型的数组,每个objc_property_attribute_t元素是属性描述信息的一个特性
objc_property_attribute_t * property_copyAttributeList ( objc_property_t property, unsigned int *outCount );
返回属性描述信息中指定特性名称为attributeName的c字符串值
char * property_copyAttributeValue ( objc_property_t property, const char *attributeName )
为类添加新属性
@param cls 被修改的类
@param name 新属性的名称
@param attributes 新属性特性数组
@param attributeCount 新属性特性数组中元素个数,即特性的个数
@return YES if the property was added successfully, otherwise NO
BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
替换类的一个属性
@param cls 被修改的类
@param name 被修改的属性名
@param attributes 属性新的特性数组
@param attributeCount 新特性数组中元素个数,即特性的个数
void class_replaceProperty (Class cls, const char *name, const objc_property_attribute_t*attributes, unsigned int attributeCount);
*/
#import <Foundation/Foundation.h>
#import <objc/message.h>
@interface Job : NSObject
@property (nonatomic, copy) NSString *jobName;
@end
@implementation Job
@end
@interface Person : NSObject{
NSString *_address;
}
@property (nonatomic, strong) Job *job;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int32_t age;
@end
@implementation Person
-(instancetype)initWithName:(NSString *)name age:(int)age{
self = [super init];
if(self){
_address = @"北京";
(_job = [Job new]).jobName = @"engineer";
_name = name;
_age = age;
}
return self;
}
@end
void printPropertyListInfo(){
Person *person = [Person new];
Class class = [person class];
class = [Person class];
//1、获取属性描述信息数组,数组中有count个objc_property_t类型的属性描述信息
unsigned int count = 0;
objc_property_t *propertyList = class_copyPropertyList(class, &count);
//遍历打印每个属性描述信息
for (int i = 0; i < count; i++) {
objc_property_t property = propertyList[i];
const char *property_Name = property_getName (property);
NSLog(@"property_Name = %s", property_Name);
const char *property_Attributes = property_getAttributes (property);
NSLog(@"property_Attributes = %s", property_Attributes);
unsigned int outCount = 0;
objc_property_attribute_t *property_AttributeList = property_copyAttributeList (property, &outCount);
for (int j = 0; j < outCount; j++) {
objc_property_attribute_t propertyAttribute = property_AttributeList[j];
NSLog(@"propertyAttribute.name = %s, propertyAttribute.value = %s", propertyAttribute.name, propertyAttribute.value);
NSLog(@"propertyAttribute.value = %s", property_copyAttributeValue(property, propertyAttribute.name));
}
NSLog(@"---------------------------------");
}
}
void addNewProperty(){
Class cls = [Person class];
//组织新属性特性数组
objc_property_attribute_t attr0 = { "T", "@\"NSDictionary\"" };
objc_property_attribute_t attr1 = { "&", "" };
objc_property_attribute_t attr2 = { "N", "" };
objc_property_attribute_t attr3 = { "V", "_newProperty" };
objc_property_attribute_t attrs[] = { attr0, attr1, attr2,attr3 };
//添加一个名字为newProperty的NSDictionary类型的属性
BOOL ret = class_addProperty ( cls, "newProperty", attrs, 4 );
if (ret) {
printPropertyListInfo();
}
}
void replaceProperty(){
Class cls = [Person class];
//组织新的特性数组
objc_property_attribute_t attr0_ = { "T", "\"NSArray\"" };
objc_property_attribute_t attr1_ = { "&", "" };
objc_property_attribute_t attr2_ = { "N", "" };
objc_property_attribute_t attr3_ = { "V", "_newProperty" };
objc_property_attribute_t attrs_[] = { attr0_, attr1_, attr2_, attr3_ };
//替换现有的author属性的类型为数组类型
class_replaceProperty ( cls, "newProperty", attrs_, 4);
printPropertyListInfo();
}
//类的实列变量,注意:变量个数>=属性个数(@property...),因为声明属性时,编译器自动添加实例变量
void printIvarList(){
Person *person = [[Person alloc]initWithName:@"jack" age:26];
unsigned int numIvars = 0;
//获取类的所有成员变量instance variable
Ivar * ivars = class_copyIvarList([person class], &numIvars);
for(int i = 0; i < numIvars; i++) {
//得到单个的成员变量
Ivar thisIvar = ivars[i];
//得到这个成员变量的类型
const char *type = ivar_getTypeEncoding(thisIvar);
NSString *stringType = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
/*此处判断非object-c类型时跳过
if (![stringType hasPrefix:@"@"]) {
continue;
}*/
//得到成员变量名
NSString *variableName = [NSString stringWithUTF8String:ivar_getName(thisIvar)];
//得到成员变量的值
id value = [person valueForKey:variableName];
NSLog(@"类型=%@, 变量名=%@, 变量值=%@", stringType, variableName, value);
}
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
printPropertyListInfo();
printIvarList();
}
return 0;
cls:指定获取的是哪个类的属性描述信息数组,即objc_property_t类型数组
outCount:输出指针,指明返回objc_property_t类型数组的大小
返回objc_property_t类型的数组,每个objc_property_t元素描述一个属性的信息,这个数组中不会包括超类的属性
objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount )
property:指定属性描述信息
返回属性描述信息中的属性名称的c字符串
const char * property_getName ( objc_property_t property )
property:指定属性描述信息
返回属性描述信息中所有特性的c字符串(固定格式,以逗号隔开,通常是T@"类型"开头,V_属性名称结尾的格式),类似于NSObject的description方法返回值
const char * property_getAttributes ( objc_property_t property );
property:指定属性描述信息
outCount:输出指针,指明返回objc_property_attribute_t类型数组的大小
返回objc_property_attribute_t类型的数组,每个objc_property_attribute_t元素是属性描述信息的一个特性
objc_property_attribute_t * property_copyAttributeList ( objc_property_t property, unsigned int *outCount );
返回属性描述信息中指定特性名称为attributeName的c字符串值
char * property_copyAttributeValue ( objc_property_t property, const char *attributeName )
为类添加新属性
@param cls 被修改的类
@param name 新属性的名称
@param attributes 新属性特性数组
@param attributeCount 新属性特性数组中元素个数,即特性的个数
@return YES if the property was added successfully, otherwise NO
BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
替换类的一个属性
@param cls 被修改的类
@param name 被修改的属性名
@param attributes 属性新的特性数组
@param attributeCount 新特性数组中元素个数,即特性的个数
void class_replaceProperty (Class cls, const char *name, const objc_property_attribute_t*attributes, unsigned int attributeCount);
*/
#import <Foundation/Foundation.h>
#import <objc/message.h>
@interface Job : NSObject
@property (nonatomic, copy) NSString *jobName;
@end
@implementation Job
@end
@interface Person : NSObject{
NSString *_address;
}
@property (nonatomic, strong) Job *job;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int32_t age;
@end
@implementation Person
-(instancetype)initWithName:(NSString *)name age:(int)age{
self = [super init];
if(self){
_address = @"北京";
(_job = [Job new]).jobName = @"engineer";
_name = name;
_age = age;
}
return self;
}
@end
void printPropertyListInfo(){
Person *person = [Person new];
Class class = [person class];
class = [Person class];
//1、获取属性描述信息数组,数组中有count个objc_property_t类型的属性描述信息
unsigned int count = 0;
objc_property_t *propertyList = class_copyPropertyList(class, &count);
//遍历打印每个属性描述信息
for (int i = 0; i < count; i++) {
objc_property_t property = propertyList[i];
const char *property_Name = property_getName (property);
NSLog(@"property_Name = %s", property_Name);
const char *property_Attributes = property_getAttributes (property);
NSLog(@"property_Attributes = %s", property_Attributes);
unsigned int outCount = 0;
objc_property_attribute_t *property_AttributeList = property_copyAttributeList (property, &outCount);
for (int j = 0; j < outCount; j++) {
objc_property_attribute_t propertyAttribute = property_AttributeList[j];
NSLog(@"propertyAttribute.name = %s, propertyAttribute.value = %s", propertyAttribute.name, propertyAttribute.value);
NSLog(@"propertyAttribute.value = %s", property_copyAttributeValue(property, propertyAttribute.name));
}
NSLog(@"---------------------------------");
}
}
void addNewProperty(){
Class cls = [Person class];
//组织新属性特性数组
objc_property_attribute_t attr0 = { "T", "@\"NSDictionary\"" };
objc_property_attribute_t attr1 = { "&", "" };
objc_property_attribute_t attr2 = { "N", "" };
objc_property_attribute_t attr3 = { "V", "_newProperty" };
objc_property_attribute_t attrs[] = { attr0, attr1, attr2,attr3 };
//添加一个名字为newProperty的NSDictionary类型的属性
BOOL ret = class_addProperty ( cls, "newProperty", attrs, 4 );
if (ret) {
printPropertyListInfo();
}
}
void replaceProperty(){
Class cls = [Person class];
//组织新的特性数组
objc_property_attribute_t attr0_ = { "T", "\"NSArray\"" };
objc_property_attribute_t attr1_ = { "&", "" };
objc_property_attribute_t attr2_ = { "N", "" };
objc_property_attribute_t attr3_ = { "V", "_newProperty" };
objc_property_attribute_t attrs_[] = { attr0_, attr1_, attr2_, attr3_ };
//替换现有的author属性的类型为数组类型
class_replaceProperty ( cls, "newProperty", attrs_, 4);
printPropertyListInfo();
}
//类的实列变量,注意:变量个数>=属性个数(@property...),因为声明属性时,编译器自动添加实例变量
void printIvarList(){
Person *person = [[Person alloc]initWithName:@"jack" age:26];
unsigned int numIvars = 0;
//获取类的所有成员变量instance variable
Ivar * ivars = class_copyIvarList([person class], &numIvars);
for(int i = 0; i < numIvars; i++) {
//得到单个的成员变量
Ivar thisIvar = ivars[i];
//得到这个成员变量的类型
const char *type = ivar_getTypeEncoding(thisIvar);
NSString *stringType = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
/*此处判断非object-c类型时跳过
if (![stringType hasPrefix:@"@"]) {
continue;
}*/
//得到成员变量名
NSString *variableName = [NSString stringWithUTF8String:ivar_getName(thisIvar)];
//得到成员变量的值
id value = [person valueForKey:variableName];
NSLog(@"类型=%@, 变量名=%@, 变量值=%@", stringType, variableName, value);
}
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
printPropertyListInfo();
printIvarList();
}
return 0;
}
下面是swift先关运行时实现
/*
func getPropertyListOfPerson() -> Void {
var count: UInt32 = 0
if let list = class_copyPropertyList(Person.self, &count) {
print("Person属性个数是:\(count)")
for i in 0..<count{
let pty = list[Int(i)]
let cName = property_getName(pty)
print("属性名:\(String(utf8String: cName) ?? "")")
}
free(list)
}
print("---------------------------------------")
}
func getIvarListOfPerson() -> Void {
var count: UInt32 = 0
if let list = class_copyIvarList(Person.self, &count) {
print("Person成员变量个数是:\(count)")
for i in 0..<count{
let ivar = list[Int(i)]
if let cName = ivar_getName(ivar){
print("实例变量名:\(String(utf8String: cName) ?? "")")
}
}
free(list)
}
print("---------------------------------------")
}
func geInstancetMethodListOfPerson() -> Void {
var count: UInt32 = 0
if let list = class_copyMethodList(Person.self, &count) {
print("Person实例方法个数是:\(count)")
for i in 0..<count{
let method = list[Int(i)]
let selector = method_getName(method)
print("实例方法名:\(NSStringFromSelector(selector))")
}
free(list)
}
print("---------------------------------------")
}
//To get the class methods of a class, use class_copyMethodList(object_getClass(cls), &count).
func getClassMethodOfPerson() -> Void {
var count: UInt32 = 0
if let list = class_copyMethodList(object_getClass(Person.self), &count) {
print("Person类方法个数是:\(count)")
for i in 0..<count{
let method = list[Int(i)]
let selector = method_getName(method)
print("类方法名:\(NSStringFromSelector(selector))")
}
free(list)
}
print("---------------------------------------")
}
func getProtocolListOfPerson() -> Void {
let p = Person(dic: Dictionary())
p.proMethodofPerson()
var count: UInt32 = 0
if let list = class_copyProtocolList(object_getClass(Person.self), &count) {
print("Person遵守的协议个数是:\(count)")
for i in 0..<count{
let pro = list[Int(i)]
let cName = protocol_getName(pro)
print("协议名:\(String(utf8String: cName) ?? "")")
}
}
print("---------------------------------------")
}
*/