链接:http://blog.csdn.net/mumubumaopao/article/details/51931424
runtime的运用: (以下代码全部都基于Dog类创建的一个对象:dog)
1.使用id类型来创建变量以便接受不同类型的对象.
2.使用[person performSelector:@selector(test2:) withObject:@"传入参数"];动态调用方法;
3.使用objc_setAssociatedObject(id object,const void *key,id value,objc_AssociationPolicy
policy)为对象object添加额外的存储空间一般用保证局部变量不会被释放掉.
4.动态copy对象(在MRC模式下使用):
Dog *dog = [Dog new];
dog.name = @"1234";
dog.age = 3;
Dog *copyDog = object_copy(dog,sizeof(dog));
5.动态设置对象的归属类object_setClass 或者获得对象的归属类
object_setClass示例代码:
Dog *dog = [Dog new];
NSLog(@"dog.class==%@",[dogclass]);
NSLog(@"%@",object_setClass(dog, [Catclass])); //Object_setClass的返回值为对象原来的所属类
NSLog(@"dog.class==%@",[dogclass]);
将输出:
dog.class==Dog
Dog
dog.class==Cat
object_getClass示例代码:
Dog *dog = [Dognew];
Class class = object_getClass(dog);
NSLog(@"%@",class);
将输出:Dog
动态的获得dog对象的所属类。
6.respondsToSelector 以及 performSelector
respondsToSelector,用来判断对象是否可以调用对应的方法,传入一个SEL类型的值
performSelector用来直接使用对象调用方法,传入一个SEL类型的参数,经常将两者结合来用,示例如下:
if ([dog respondsToSelector:@selector(funOfDog)]) {
[dog performSelector:@selector(funOfDog)];
}else if([dogrespondsToSelector:@selector(funOfCat)]){
[dog performSelector:@selector(funOfCat)];
}
判断dog类可以相应那种方法并且直接调用它.
7.使用object_getClassName获取类名,只不过是C++字符串的格式
const char * className =object_getClassName(dog);
printf("%s",className);
输出:Dog
8.为对象添加方法
为Dog类添加私有方法,因为这个方法是动态添加的,所以只能使用使用respondsToSelector来动态的调用这个方法,否则的话,编译是不通过的,因为在被添加的类中,该方法即没有实现也没有声明.
class_addMethod([Dogclass], @selector(dogAddFun:str2:), (IMP)funOfAdd,"i@:@@");
if ([dog respondsToSelector:@selector(dogAddFun:str2:)]) {
int number = [dogperformSelector:@selector(dogAddFun:str2:)withObject:@"1234"withObject:@"5678"];
NSLog(@"%d",number);
}else
NSLog(@"方法没有添加成功");
funOfAdd方法定义:
int funOfAdd(idself,SEL_cmd,NSString *str,NSString* str2){
return (int)(str.length + str2.length);
} //返回两个字符串长度相加的和
9.获取一个类的所有方法 class_copyMethodList
u_int count;
Method*methods =class_copyMethodList([dogclass], &count);
for(inti =0; i < count; i ++){
SELname =method_getName(methods[i]);
printf("%s\n",sel_getName(name));
}
其中,class_copyMethodList的两个参数分别为类名和统计方法数量的无符号整形的变量地址,其返回值为一个包含该类所有objc_method方法的数组
method_getName传入的参数是该类中的objc_method对象,返回值为该方法对应的SEL,其在runtime源码中的实现如下
SELmethod_getName(Methodm)
{
if(!m)returnNULL;
returnoldmethod(m)->method_name;
}
sel_getName(name)则是通过SEL获取该SEL对应的方法名
10.获取一个类的所有属性名
u_intcount;
objc_property_t* properites =class_copyPropertyList([dogclass], &count);
for(inti =0; i < count;i ++){
constchar* name=property_getName(properites[i]);
printf("%s\n",name);
}
class_copyPropertyList返回一个包含该类所有属性的数组,property_getName获得该objc_property_t对应的属性名 的字符串.
11.系统类方法的替换
可以互换两个方法的实现 ,但是没感觉有什么用途 ,估计是没遇到有次需求的问题
Methodmethod1 =class_getInstanceMethod([NSStringclass],@selector(lowercaseString));
Methodmethod2 =class_getInstanceMethod([NSStringclass],@selector(uppercaseString));
method_exchangeImplementations(method1, method2);
NSLog(@"%@",[@"aaaaaa"lowercaseString]);
NSLog(@"%@",[@"BBBBB"uppercaseString]);
12.实现自定义方法的替换
Methodmethod1 =class_getInstanceMethod([dogclass],@selector(funOfDog));
MethodfunMethod =class_getInstanceMethod([selfclass],@selector(replaseFun));
IMPimp =method_getImplementation(funMethod);
method_setImplementation(method1, imp);
[dogfunOfDog];
funOfDog是dog类里定义的方法,replaseFun是在调用控制器里定义的方法,两个方法都只有一条输出语句,执行完上述语句后,dog调用funOfDog执行的是在本控制器里输出的语句.
加入审核被拒交流群,一起交流审核上架经验吧~~ 群号:689757099