Objective-C Method Swizzling理解不了?

Objective-C Method Swizzling增强注释版。有些代码可能拿过来能直接用,但是我们并不知道其原理或者理解想法,所以总是一知半解。昨天看了下Objective-C Method Swizzling,这是很典型的案例,因为很绕!(只有我觉得绕吗?看着看着自己就懵了[手动一脸懵逼]),所以自己加了点注释,帮助下理解(可能理解的不对,大家不吝赐教吧!)

我理解的哈~:重点就是方法名和方法的实现 我们要区别开 - (void)...; 是方法的声明 - (void)...{}这个是方法的实现,交换方法的原理其实就是维持方法申明不变,然后交换两个方法的实现,引起的结果就是 调用a方法:[... a],而实际上调用的是b方法的实现:-b{},反之亦然。

+ (void)load {

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

Class class = [self class]; //替换的是对象(实例)方法

//!重点强调下 如果替换的是类方法 格式应该是

Class class = object_getClass[self class];

//        SEL originalSelector = @selector(viewWillAppear:);

//        SEL swizzledSelector = @selector(mrc_viewWillAppear:);

      SEL originalSelector = @selector(log);

      SEL swizzledSelector = @selector(customLog);

//对象方法替换

      Method originalMethod = class_getInstanceMethod(class, originalSelector);

      Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

//类方法替换

      Method originalClassMethod = class_getClassMethod(class, originalSelector);

      Method swizzledClassMethod = class_getClassMethod(class, swizzledSelector);

///----------------------------------------

/// @name 最核心需要理解的代码

///----------------------------------------

BOOL success =

class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));

//        class_addMethod 为originalSelector方法添加实现 成功:说明该方法没有在.m中实现 于是就把swizzledMethod的实现添加给了originalSelector  失败:说明该方法有在.m中实现了 那么就将两个方法的实现进行替换 注意 是替换实现 而不是方法名

//Method 组成是个结构体 成分:SELname:方法名; constchar*types:参数; IMPimp:实现;

//class_addMethod照我的理解 就是添加一个结构体,然后给SEL和IMPimp赋值,所以这里其实也是给originalSelector替换好了实现(成功success=yes)

//success 作用:

//如果返回YES 说明这个类.m没有实现了这个方法(那么肯定是父类实现了)这里我之前有个疑问,如果originalMethod
一直没有实现,或者都不存在呢?那下面的class_replaceMethod导致的后果难道不是奔溃吗?因为你用了一个不存在的实现去替换另一个方法的声明,一调用不是炸了?后来我想了想,originalMethod不存在我们也没法调用对不对,替换了有怎么样?我们没法去调用呀!originalMethod只声明不实现呢?那肯定奔溃呀!这不很正常么~"茅厕顿开"

if (success) {

      class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));

}

//如果返回NO 说明这个类.m实现了这个方法

else {

      method_exchangeImplementations(originalMethod, swizzledMethod);//交换两个方法的实现

//e.g 调mrc_viewWillAppear方法,联动的是viewWillAppear的实现

//调viewWillAppear方法,联动的是的实现mrc_viewWillAppear

}

      NSLog(@"loadReady");

});

}

#pragma mark - Method Swizzling

//重点在这,乍一看不是循环调用了吗?要记住一点 方法的声明和方法的调用不是一个概念

- (void)customLog{//这是方法的实现

      [self customLog];//这是通过方法的声明调用对应方法的实现 而在这里customLog方法的实现已经被我们替换掉了

       NSLog(@"====");

}

你可能感兴趣的:(Objective-C Method Swizzling理解不了?)