美文网首页
个人常用Runtime的两种使用方法

个人常用Runtime的两种使用方法

作者: 0143fc60fe45 | 来源:发表于2016-03-09 17:28 被阅读71次

    Runtime是OC中的黑魔法。个人在项目中使用到Runtime的地方比较少,主要是以下两种:

    1.动态为类添加属性:主要使用场景为类目(category)添加属性。

    这里的例子是为UIButton+Suggest添加属性propertyA。

    @interface UIButton (Suggest)

    @property(nonatomic,strong) NSString *propertyA;

    @end

    @implementation UIButton (Suggest)

    staticchar*PropertyA ="PropertyA";

    -(void)setPropertyA:(UITabBarController*)propertyA {

    /*

    OBJC_ASSOCIATION_ASSIGN;//assign策略

    OBJC_ASSOCIATION_COPY_NONATOMIC;//copy策略

    OBJC_ASSOCIATION_RETAIN_NONATOMIC;// retain策略

    OBJC_ASSOCIATION_RETAIN;

    OBJC_ASSOCIATION_COPY;

    */

    /*

    * id object给哪个对象的属性赋值

    const void *key属性对应的key

    id value设置属性值为value

    objc_AssociationPolicy policy使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC

    objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);

    */

    objc_setAssociatedObject(self,PropertyA, propertyA,OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    }

    - (NSString*)propertyA {

    return objc_getAssociatedObject(self,PropertyA);

    }


    2.方法交换:使用场景主要是在iOS中实现面向切面编程思想。

    下面是Mattt大神在NSHipster上的文章自己写的代码。

    #import "UIViewController+swizzling.h"

    #import

    @implementation UIViewController (swizzling)

    //load方法会在类第一次加载的时候被调用

    //调用的时间比较靠前,适合在这个方法里做方法交换

    + (void)load{

    //方法交换应该被保证,在程序中只会执行一次

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    //获得viewController的生命周期方法的selector

    SEL systemSel = @selector(viewWillAppear:);

    //自己实现的将要被交换的方法的selector

    SEL swizzSel = @selector(swiz_viewWillAppear:);

    //两个方法的Method

    Method systemMethod = class_getInstanceMethod([self class], systemSel);

    Method swizzMethod = class_getInstanceMethod([self class], swizzSel);

    //首先动态添加方法,实现是被交换的方法,返回值表示添加成功还是失败

    BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));

    if (isAdd) {

    //如果成功,说明类中不存在这个方法的实现

    //将被交换方法的实现替换到这个并不存在的实现

    class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));

    }else{

    //否则,交换两个方法的实现

    method_exchangeImplementations(systemMethod, swizzMethod);

    }

    });

    }

    - (void)swiz_viewWillAppear:(BOOL)animated{

    //这时候调用自己,看起来像是死循环

    //但是其实自己的实现已经被替换了

    [self swiz_viewWillAppear:animated];

    NSLog(@"swizzle");

    }

    @end

    在一个自己定义的viewController中重写viewWillAppear

    - (void)viewWillAppear:(BOOL)animated{

    [super viewWillAppear:animated];

    NSLog(@"viewWillAppear");

    }


    关于Runtime实用的,还有一种是动态生成Model,网上有很多优秀的例子,这里就不说了。

    这篇是关于Runtime实用的,先到这里。希望大家指点出不足与错误之处。

    相关文章

      网友评论

          本文标题:个人常用Runtime的两种使用方法

          本文链接:https://www.haomeiwen.com/subject/xoxtlttx.html