Objective-C 虽然是基于C的面向对象的语言,但是它和C++的面向对象不一样。C++中类的成员变量、方法在编译期已经决定了,Objective-C中是在运行期由runtime调用的。我们通过runtime可以随意修改Objective-C的类。
在使用runtime提供的函数之前,我们需要了解几个数据类型(大部分源码在objc/objc.h、objc/runtime.h、objc/message.h中)。
Class //表示类的结构体
SEL //表示selector的结构体
id //表示类实例的结构体
Method //表示类/对象的方法的结构体
Ivar //表示实例的成员变量的值得结构体
1.获取相关信息
//获取类名称
const char *class_getName(Class cls)
//获取对象的变量信息
Ivar class_getInstanceVariable(Class cls, const char *name)
//获取类的属性信息
objc_property_t class_getProperty(Class cls, const char *name)
//获取方法的实现
IMP class_getMethodImplementation(Class cls, SEL name)
//获取实例方法信息,即“-”方法
Method class_getInstanceMethod(Class cls, SEL name)
//获取类方法信息,即“+”方法
Method class_getClassMethod(Class cls, SEL name)
2.获取成员变量的信息以及修改实例的成员变量的值
unsigned int listCount = 0;
//获取实例的所有的成员变量信息,包括私有的
Ivar *ivars = class_copyIvarList([m class], &listCount);
//listCount 为 1
for (unsigned int i = 0; i < listCount; i++)
{
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
const char *type = ivar_getTypeEncoding(ivar);
//设置实例的成员变量的值
object_setIvar(m, ivar, @"my new class");
//获取实例的成员变量的值
id value=object_getIvar(m, ivar);
NSLog(@"\n成员变量名:%s 类型:%s 值:%@\n",name,type,value);
}
//copy的函数需要手动释放
free(ivars);
3.获取类的属性信息
//获取所有的属性信息,包括私有的
objc_property_t*propertyList=class_copyPropertyList([MyClass class], &listCount);
for (int i = 0; i < listCount; i++)
{
objc_property_t property = propertyList[i];
const char* propertyName=property_getName(property);
const char* attr=property_getAttributes(property);
NSLog(@"\n属性名:%s 特性:%s\n",propertyName,attr);
}
free(propertyList);
返回的结果:
解析一下属性的相关信息:
T@"NSString" //返回值
& //C(copy) &(strong) W(weak)空(assign)
N //空(atomic) N(Nonatomic)
V_className //属性名
4.获取对象的方法
//获取所有的方法信息,包括私有的,不包括类的方法
Method* methodList=class_copyMethodList([MyClass class],&listCount);
for (int i = 0; i < listCount; i++)
{
Method method = methodList[i];
const char* methodName=sel_getName(method_getName(method));
char returnType[64];
method_getReturnType(method, returnType, 64);
NSLog(@"\n方法名:%s 返回值:%s\n",methodName,returnType);
}
free(methodList);
Objective-C的runtime最大的用处还是修改类/对象的方法,使用相关的函数我们甚至可以修改替换Apple提供的类中的方法。
如有错误,欢迎指出!