iOS端 分类方法覆盖本类方法处理

1,457 阅读2分钟

广点通和今日头条广告SDK,回调方法名相同的冲突解决

问题描述:
两个广告SDK的回调,我一个写在了分类里,导致分类里(头条)回调方法,覆盖了本类里(广点通)回调方法,因为方法名字和参数完全相同,巧不巧😿,虽然参数类型不同。

补充:
分类并没有覆盖主类的同名方法,只是Category的方法排在方法列表前面,主类的方法被移到了方法列表的后面。

本打算用Runtime的方法互换,从方法列表里拿回原方法,从而调用,但发现每次都会互换,也不能解决,方法代码如下:

-(void) exchangeMainCategoryMethod:(id)target selector:(SEL)selector{
    // Get the class method list
    uint count;
    Method *methodList = class_copyMethodList([target class], &count);
    Method firstMethod = nil ;
    Method lastMethod = nil ;
    for (int i = 0; i < count; i++) {
        Method method = methodList[i];
        NSLog(@"Category catch selector : %d %@", i, NSStringFromSelector(method_getName(method)));
        SEL name = method_getName(method);
        if (name == selector) {
            if(!firstMethod){
                firstMethod = method ;
                lastMethod = method ;
            }else{
                lastMethod = method ;
            }
        }
    }
    if(firstMethod && lastMethod && firstMethod!=lastMethod){
        method_exchangeImplementations(firstMethod, lastMethod) ;
    }
}

解决方法:
还是用runtime方法互换解决,在单例里声明一个熟悉advCallBack_isGDT(默认NO), 暴露出两个方法:获取属性值,修改属性值。每次App启动时,默认为NO,因为此时分类里的头条回调方法在主类里广点通回调方法前,在展示广告时,判断是否需要互换方法,伪代码如下:

case GDT:{
    if(![USER_MANAGER getAdvCallback_isGDT]) {
        [self changeCallbackMethodToGDT:YES];
    }
    
    //发起广点通广告请求代码
}
    break;
    
case JRTT:{
    if([USER_MANAGER getAdvCallback_isGDT]) {
        [self changeCallbackMethodToGDT:NO];
    }
    
    //发起头条广告请求代码
}

- (void)changeCallbackMethodToGDT:(BOOL)changeToGDT {
    //runtime处理, 分类里的头条回调方法和GDT重名, 会覆盖GDT回调方法
    [self exchangeMainCategoryMethod:self   selector:@selector(nativeExpressAdSuccessToLoad:views:)];
    [self exchangeMainCategoryMethod:self   selector:@selector(nativeExpressAdViewRenderSuccess:)];
    
    [USER_MANAGER setAdvCallback_isGDT:changeToGDT];
}