iOS Swizzle Method

1.实例方法交换

+ (void)load
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{

  Method origleMe = class_getInstanceMethod([self class], @selector(viewWillAppear:)); // 如果子类没有实现  这个获取到的是superClass的方法
  Method newMe = class_getInstanceMethod([self class], @selector(my_viewWillAppear:));

// 这个方法  往类里面添加 方法
//1.如果类没有实现这个方法,class_addMethod给类添加一个方法,方法的选择器还是它本身,方法的实现和参数类型都是要替换的新的方法,这种情况返回的bool是YES,在调用class_replaceMethod替换新增的方法的实现为继承的superclass的方法实现,

// 疑问1 class_addMethod 如果添加成功,添加的方法的实现其实是新增的方法的实现,class_replaceMethod 替换的时候获取方法IMP时候应该用最开始获取的method,如果不这样有可能用,再次获取Method那么class_replaceMethod替换的还是新增的方法,相当于系统的和新的方法的实现都是新增的实现 验证 正确 ,如果这样写 会循环调用
 //2.如果类里面以及有这个方法,class_addMethod添加失败,直接交换两个方法的实现即可
   BOOL isSuccess = class_addMethod([self class], @selector(viewWillAppear:), method_getImplementation(newMe), method_getTypeEncoding(newMe));

// 测试 疑问1
//    Method aOrigleMe = class_getInstanceMethod([self class], @selector(viewWillAppear:));
   if (isSuccess) {
        class_replaceMethod([self class], method_getName(newMe), method_getImplementation(origleMe), method_getTypeEncoding(origleMe));
// 测试 疑问1
//      class_replaceMethod([self class], method_getName(newMe), method_getImplementation(aOrigleMe), method_getTypeEncoding(aOrigleMe));
    } else {
        method_exchangeImplementations(origleMe, newMe);
    }
  });
}
- (void)my_viewWillAppear:(BOOL)animated
{
     [self my_viewWillAppear:animated];
//  [self viewWillAppear:animated];
     NSLog(@"%s",__func__);
}

2.类方法交换

+ (void)load
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
  // 这个应为要获取类方法,所以需要获取到元类对象
  // 因为实例方法存放在类对象里面,类方法存放在元类对象里面
  Class aClass = object_getClass(self);


  SEL orgiSel = @selector(testOrgiClassMethod);
  SEL newSel = @selector(testNewClassMethod);

  Method oriClassMe = class_getClassMethod(aClass, orgiSel);
  Method newClassMe = class_getClassMethod(aClass, newSel);    
    BOOL isSuccess = class_addMethod(aClass, orgiSel, method_getImplementation(newClassMe), method_getTypeEncoding(newClassMe));
    if (isSuccess) {
      class_replaceMethod(aClass, newSel, method_getImplementation(oriClassMe), method_getTypeEncoding(oriClassMe));
    } else {
    method_exchangeImplementations(oriClassMe, newClassMe);
    }
  });
}

+ (void)testOrgiClassMethod
{
  NSLog(@"%s",__func__);
}

+ (void)testNewClassMethod
{
  NSLog(@"%s",__func__);
}

3.class一点总结

// +(Class)class{return self}  -(Class)class{return object_getClass(self)}
/*  
 实例对象
 1. -(Class)class; 获取到类对象
 2. object_getClass(self); 获取到类对象
 3. object_getClass([self class]); 获取元类
 类对象
 1.+(Class)class; 获取到还是本身
 2.object_getClass(self); 获取到元类对象
 3.object_getClass([self class]); 获取元类对象


 // 为神魔  在一个类里面 [self class] == [super class];

 应为oc的方法调用都会是转成消息
 [self class] 会调用 objc_msgSend(self,@selecter(class)); 
 [super class] 会调用  objc_msgSendSuper(struct objc_super *super, SEL)

// 这个结构体里面的 receiver 就是self 调用super时他会从父类开始查找class的方法,但是消息的接受者还是 self ,所以打印的它俩相同

   struct objc_super {
      Specifies an instance of a class.
      __unsafe_unretained id receiver;

      Specifies the particular superclass of the instance to message.
      #if !defined(__cplusplus)  &&  !__OBJC2__
      For compatibility with old objc-runtime.h header
      __unsafe_unretained Class class;
      #else
      __unsafe_unretained Class super_class;
      #endif
      super_class is the first class to search
    };


 // 发消息,系统会自动从下面几个中间挑选合适的调用

   objc_msgSend  objc_msgSend_stret  objc_msgSendSuper  objc_msgSendSuper_stret

   * @note When it encounters a method call, the compiler generates a call to one of the
   *  functions \c objc_msgSend, \c objc_msgSend_stret, \c objc_msgSendSuper, or \c objc_msgSendSuper_stret.
   *  Messages sent to an object’s superclass (using the \c super keyword) are sent using \c objc_msgSendSuper;
   *  other messages are sent using \c objc_msgSend. Methods that have data structures as return values
   *  are sent using \c objc_msgSendSuper_stret and \c objc_msgSend_stret.
*/

项目地址:https://github.com/hkkh/iOS-Swizzle-Method.git

你可能感兴趣的:(iOS Swizzle Method)