60

KZWFoudation系列之Router的设计

 5 years ago
source link: http://www.10tiao.com/html/216/201806/2652561558/2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本来是要写我自己用的router的,但是现在这个有点落后了, 所以这篇文章主要说下CTMediator这个router的设计,我觉得这个比较符合当下我对router理解。


它主要有一个类CTMediator,里面有3个方法,performActionWithUrl,performTarget和releaseCachedTargetWithTargetName前2个的作用主要是返回controller,后一个是清除缓存。performActionWithUrl是根据url解析出所需要的数据在调用performTarget生成controller,下面来看下performTarget这个主要方法:


- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget
{
    NSString *targetClassString = [NSString stringWithFormat:@"Target_%@", targetName];
    NSString *actionString = [NSString stringWithFormat:@"Action_%@:", actionName];
    Class targetClass;
    NSObject *target = self.cachedTarget[targetClassString];
    if (target == nil) {
        targetClass = NSClassFromString(targetClassString);
        target = [[targetClass alloc] init];
    }
    SEL action = NSSelectorFromString(actionString);
    if (target == nil) {
        // 这里是处理无响应请求的地方之一,这个demo做得比较简单,如果没有可以响应的target,就直接return了。实际开发过程中是可以事先给一个固定的target专门用于在这个时候顶上,然后处理这种请求的
        [self NoTargetActionResponseWithTargetString:targetClassString selectorString:actionString originParams:params];
        return nil;
    }
    if (shouldCacheTarget) {
        self.cachedTarget[targetClassString] = target;
    }
    if ([target respondsToSelector:action]) {
        return [self safePerformAction:action target:target params:params];
    } else {
        // 有可能target是Swift对象
        actionString = [NSString stringWithFormat:@"Action_%@WithParams:", actionName];
        action = NSSelectorFromString(actionString);
        if ([target respondsToSelector:action]) {
            return [self safePerformAction:action target:target params:params];
        } else {
            // 这里是处理无响应请求的地方,如果无响应,则尝试调用对应target的notFound方法统一处理
            SEL action = NSSelectorFromString(@"notFound:");
            if ([target respondsToSelector:action]) {
                return [self safePerformAction:action target:target params:params];
            } else {
                // 这里也是处理无响应请求的地方,在notFound都没有的时候,这个demo是直接return了。实际开发过程中,可以用前面提到的固定的target顶上的。
                [self NoTargetActionResponseWithTargetString:targetClassString selectorString:actionString originParams:params];
                [self.cachedTarget removeObjectForKey:targetClassString];
                return nil;
            }
        }
    }
}


targetName就是调用接口的Object,actionName就是调用方法的SEL,params是参数,shouldCacheTarget代表是否需要缓存,如果需要缓存就把target存起来,Key是targetClassString,Value是target。


通过这种方式进行改造的,外面调用的方法都很统一,都是调用performTarget: action: params: shouldCacheTarget:。第三个参数是一个字典,这个字典里面可以传很多参数,只要Key-Value写好就可以了。处理错误的方式也统一在一个地方了,target没有,或者是target无法响应相应的方法,都可以在Mediator这里进行统一出错处理。


但是在实际开发过程中,不管是界面调用,组件间调用,在Mediator中需要定义很多方法。于是做作者又想出了建议我们用Category的方法,对Mediator的所有方法进行拆分,这样就就可以不会导致Mediator这个类过于庞大了。所以可以看下demo中的#import "CTMediator+CTMediatorModuleAActions.h"是怎么管理的。


代码地址:

https://github.com/casatwy/CTMediator
参考文章:

https://lpd-ios.github.io/2017/02/26/iOS-Router/


作者:moonCoder
链接:https://www.jianshu.com/p/66d07bfa78e4


相关推荐:



Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK