OC 中如何做到分类方法不覆盖原方法

今天在用 ShareSDK 做第三方登录的时候,发现使用旧版 SDK 时是在 AppDelegate.m 文件里手动实现 2 个处理客户端返回消息的回调方法,如下图

OC 中如何做到分类方法不覆盖原方法_第1张图片

而新版 SDK 却不需要。那么问题来了,新版是在哪里实现处理客户端返回消息的回调方法?

要知道,处理回跳必须需要实现以下方法

iOS 9 以下用这个

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation

iOS 9 及以上用这个

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options

我猜想 ShareSDK 是用 AppDelegate 的分类实现了方法,但一般情况下,在OC中只要分类实现了方法,那么类中的原来实现方法就不会被调用。 而现在这个方法我们可以自定义实现,且不影响第三方客户端回跳,怎么做???

其实要做到分类方法不覆盖原方法需要用的 OC 的 Runtime ,来测试一下

在 AppDelegate.m 中实现 applicationDidBecomeActive:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    NSLog(@"applicationDidBecomeActive");
}

再创建一个 AppDelegate 的分类,实现applicationDidBecomeActive:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    NSLog(@"applicationDidBecomeActive--分类");
    Class currentClass = [AppDelegate class];
    if (currentClass) {
        unsigned int methodCount;
        Method *methodList = class_copyMethodList(currentClass, &methodCount);
        IMP lastImp = NULL;
        SEL lastSel = NULL;
        for (NSInteger i = 0; i < methodCount; i++) {
            Method method = methodList[i];
            NSString *methodName = [NSString stringWithCString:sel_getName(method_getName(method))
                                                      encoding:NSUTF8StringEncoding];
            if ([@"applicationDidBecomeActive:" isEqualToString:methodName]) {
                lastImp = method_getImplementation(method);
                lastSel = method_getName(method);
            }
        }
        typedef void (*fn)(id,SEL,id);
        if (lastImp != NULL) {
            fn f = (fn)lastImp;
            f(self,lastSel,application);
        }
        free(methodList);
    }
}

打印结果

2017-06-15 21:55:45.709 demo[807:25011] applicationDidBecomeActive--分类
2017-06-15 21:55:45.709 demo[807:25011] applicationDidBecomeActive

这样,就可以同时调用分类和原类的方法了,不知道 ShareSDK 是不是这样的思路

参考

对OC中Category 的理解,以及方法覆盖的解决办法

你可能感兴趣的:(OC 中如何做到分类方法不覆盖原方法)