OC Method Swizzling 使用

方法

void method_exchangeImplementations(Method m1, Method m2)

method swizzling是一个oc 的一种黑魔法他作用是交换方法的imp指针,imp指针是一个指向方法的指针,就像isa指针一样不同的是isa指向的是对象。


使用场景


最简单的一个使用,切换夜间模式的时候,我们加载两套图片。肯定执行的代码不一样,但是执行的方法名字需要一样

使用地点


一般情况情况使用地点在+load里面使用,+load是在类初始化的时候调用,+initialize是在实例化类的时候调用。所以+initialize方法可能不会被调用。
不过我这次没有在+load中调用,因为我是需要切换回来。

效果


OC Method Swizzling 使用_第1张图片
弹簧按钮.gif

现在目的是要求重写setHighlighted:方法
点击“无动画”按钮需要切换回原来的方法

带动画高亮方法

/**
 *  带动画的高亮方法
 */
-(void)AI_setAnimationHighlighted:(BOOL)animationHighlighted{
    [self spring];
}

动画

/**
*  弹簧动画
*/
-(void)spring{
   [UIView animateWithDuration:self.animationTime animations:^{
       self.transform = CGAffineTransformMakeScale(1.1, 1.1);
       self.alpha = 0.3;
   } completion:^(BOOL finished) {
       self.alpha = 1;
   }];
   self.transform = CGAffineTransformIdentity;
}

切换方法

/**
*  切换方法从A切换到B
*/
-(void)changeMethod:(SEL)actionA toMethod:(SEL)actionB{

   //原有的高亮方法
   Method aMetod =   class_getInstanceMethod([AISpringButton class],actionA);
   //动画高亮方法
   Method bMetod = class_getInstanceMethod([AISpringButton class], actionB);  
   //这句是为了保护系统的方法
   BOOL isAdd = class_addMethod([AISpringButton class], actionA, method_getImplementation(bMetod), method_getTypeEncoding(bMetod));
   if (isAdd) {
       class_replaceMethod([AISpringButton class], actionB, method_getImplementation(aMetod), method_getTypeEncoding(aMetod));
   }else{
       method_exchangeImplementations(aMetod, bMetod);
   }
}

demo地址

github:https://github.com/aizexin/AISpringButton

你可能感兴趣的:(OC Method Swizzling 使用)