runtime运用实例

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 (int i =0 ; i < count; i ++){

       SEL name =method_getName(methods[i]);

       printf("%s\n",sel_getName(name));

    }

    其中,class_copyMethodList的两个参数分别为类名和统计方法数量的无符号整形的变量地址,其返回值为一个包含该类所有objc_method方法的数组

    method_getName传入的参数是该类中的objc_method对象,返回值为该方法对应的SEL,其在runtime源码中的实现如下

SEL method_getName(Method m)

{

   if (!m)returnNULL;

   returnoldmethod(m)->method_name;

}

           sel_getName(name)则是通过SEL获取该SEL对应的方法名


10.获取一个类的所有属性名

   u_int count;

   objc_property_t* properites =class_copyPropertyList([dogclass], &count);

   for(int i =0 ; i < count;i ++){

       constchar* name=property_getName(properites[i]);

       printf("%s\n",name);

    }

   class_copyPropertyList返回一个包含该类所有属性的数组,property_getName获得该objc_property_t对应的属性名    的字符串.

11.系统类方法的替换

    可以互换两个方法的实现 ,但是没感觉有什么用途 ,估计是没遇到有次需求的问题  

    Method method1 =class_getInstanceMethod([NSStringclass],@selector(lowercaseString));

    Method method2 =class_getInstanceMethod([NSStringclass],@selector(uppercaseString));

    method_exchangeImplementations(method1, method2);

    NSLog(@"%@",[@"aaaaaa"lowercaseString]);

    NSLog(@"%@",[@"BBBBB"uppercaseString]);


12.实现自定义方法的替换

    Method method1 =class_getInstanceMethod([dogclass],@selector(funOfDog));

    Method funMethod =class_getInstanceMethod([selfclass],@selector(replaseFun));

    IMP imp =method_getImplementation(funMethod);

    method_setImplementation(method1, imp);

    [dogfunOfDog];

    

    funOfDog是dog类里定义的方法,replaseFun是在调用控制器里定义的方法,两个方法都只有一条输出语句,执行完上述语句后,dog调用funOfDog执行的是在本控制器里输出的语句.


加入审核被拒交流群,一起交流审核上架经验吧~~   群号:689757099
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值