码迷,mamicode.com
首页 > 移动开发 > 详细

iOS runtime运用实例

时间:2016-07-24 20:50:55      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

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 = [Dognew];

    dog.name = @"1234";

    dog.age = 3;

    

    Dog *copyDog = object_copy(dog,sizeof(dog));

5.动态设置对象的归属类object_setClass 或者获得对象的归属类

object_setClass如下列代码:

 

  Dog *dog = [Dognew];

    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对象的所属类

 

5.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类可以相应那种方法并且直接调用它.

6.使用object_getClassName获取类名,只不过是C+字符串的格式

const char * className =object_getClassName(dog);

   printf("%s",className);

输出:Dog

 

7.为对象添加方法

    为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);

}  //返回两个字符串长度相加的和

8.获取一个类的所有方法  class_copyMethodList

 

    u_int count;

    Method *methods = class_copyMethodList([dog class], &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) return NULL;

 

 

    return oldmethod(m)->method_name;

 

 

}

 

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

 

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

 

 u_int count;

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

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

        const char* name= property_getName(properites[i]);

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

    }

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

 

10.系统类方法的替换

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

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

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

    method_exchangeImplementations(method1, method2);

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

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

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

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

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

    IMP imp = method_getImplementation(funMethod);

 

    method_setImplementation(method1, imp);

    [dog funOfDog];

    

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

iOS runtime运用实例

标签:

原文地址:http://www.cnblogs.com/LL--Blog/p/5701466.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!