当前位置: 首页>移动开发>正文

ios router ios routers



背景

项目中有rn 和h5 的交互的各种往来,维护这个项目的时候发现了有广泛应用的在项目中的router。简单研究了一下,虽然还没有来得及对比美团,蘑菇街,等router 鼻祖级别的路由协议,也没有看掘金上班两股力量的争论,研究东西,总不会太坏

表面应用

表层的api 很简单

//注册
- (void)map:(NSString *)route toControllerClass:(Class)controllerClass;
- (void)map:(NSString *)route toBlock:(JFRouterBlock)block;

//取controller
- (UIViewController *)matchController:(NSString *)route;
- (JFRouterBlock)matchBlock:(NSString *)route;

//直接
- (id)callBlock:(NSString *)route;

//判断routeType
- (JFRouteType)canRoute:(NSString *)route;
复制代码
  1. 注册 是把对应的controller 和 router string 绑定在一起
  2. 取controller 用router 取出来 对应的controller 以达到不用import 的目的
  3. block , 这个 我之前也是不理解的,就是用于给目标的controller set 初始参数
  4. canroute,判断router 是否有效

这里说一下有意识的点,就是我看了下其他的router ,可以通过router 来传参数。表示没有看动为啥要这么做,可能为了,更好的和其他的语言编写的业务沟通吧

调用方法 block
[[JFRouter shared] map:@"hello" toBlock:^id(NSDictionary *params,id aCallback) {
        id viewController = nil;
        Class c = NSClassFromString(@"RouterTwoViewController");
        viewController = [[c alloc] init];
        [(UIViewController *)viewController setParams:params];
        return viewController;
    }];
复制代码

这里面的block 通过setParams 来传递参数。params 是通过runtime 给每个vc 加的属性。

JFRouterBlock block = [[JFRouter shared] matchBlock:@"hello"];
        UIViewController *v = block(@{@"title_jf":@"blocktitle",@"subTitle":@"hello world"},nil);
        [self.navigationController pushViewController:v animated:YES];
复制代码

这里 通过block 传参,来对param set。这也是我个人最绕的地方,后来发现,block 传值一般都是 传递初始化的值, router 对应的不是controller 而是block。这样的理解好像能好过一些

调用方法 正常调用
UIViewController *v = [[JFRouter shared] matchController:@"hello"];
        [self.navigationController pushViewController:v animated:YES];
复制代码

直接通过router 对应的controller 来调用

Class c = NSClassFromString(@"RouterTwoViewController");
   [[JFRouter shared] map:@"hello" toControllerClass:c];
复制代码

这个时候,设置parame 的方法就简单很多,直接通过rumtime 设置的字典传值,通过kvc 取。

这一切的目的为了少 引入.h文件,或者其他的模块的文件,起到解耦的目的。 这里不同技术经历的人,对解耦的理解是不一样。因为这里涉及到软件的开始经历和自己的理解。我个人的理解是根据业务的结构来区分代码的耦合度,比如有个基金模块,内部的逻辑相对理财独立,交集的点很有限,那么有交集的地方,就是路由开始使用的时候来,或者 比如你的项目中有rn 代码 ,h5 相互的调用,有个路由就很方便,没有,可能如果项目没有美团,蘑菇街那么大 可能也ok。 所以我理解到这里,我发现,如果你的项目中用到了路由,说明你的项目已经很大,或者就是为了用而用。

原理分析

block

当注册的时候

- (void)map:(NSString *)route toBlock:(JFRouterBlock)block{
    NSMutableDictionary *subRoutes = [self subRoutesToRoute:route];
    subRoutes[@"_"] = [block copy];
}
复制代码
- (NSMutableDictionary *)subRoutesToRoute:(NSString *)route{
    NSString *host = [self hostFromRoute:route];
    NSMutableDictionary *dic = self.routes[host];
    if (dic == nil) {
        dic = [NSMutableDictionary dictionary];
        self.routes[host] = dic;
    }
    return dic;
}
复制代码

当调用 matchBlock 的时候 上边的字典的内容变成了

{
    "_" = "<__NSGlobalBlock__: 0x103be9928>";
}
复制代码

当block()中传递参数的时候, map 的block 会被调用,这样,就实现了viewController 在生成的时候 被设置参数的目的。 这点可能要对block理解的比较熟悉,如果习惯了block 的用法,而忘记了block 的原理,可能这个点又能让我们回顾一下block 的本质含义。 block 中回调的时候会发现

[[JFRouter shared] map:@"hello" toBlock:^id(NSDictionary *params,id aCallback) {
        id viewController = nil;
        Class c = NSClassFromString(@"RouterTwoViewController");
        viewController = [[c alloc] init];
        [(UIViewController *)viewController setParams:params];
        return viewController;
    }];
=================================params=====output======================================
{
    subTitle = "hello world";
    "title_jf" = blocktitle;
}
复制代码

你要的参数

具体应用和争议

two 可能不需要了.h文件,这个是他最大的争论问题,如果仅仅的iOS 内部,那么这个路由,真的很让你感觉鸡肋,OC 的一大特点就是有.h 文件,让对外声明可以很好的区分。但是如果你是swift 开发,rn 开发, h5 开发,和你的项目有千丝万缕的联系,如果这个时候有个人router , 你可能就能理解了。 不过这个度还是要把握好,业务需求

完结

好久没有更新,关于路由已经是去年比较话题了,可我居然是不知道的状态,差点和时代脱节了。 最近最热的区块链,本人突然感觉兴趣来了,可能后期写一些关于智能合约的开发文章。本质估计都不会差的太远。你我共勉

这里有一些文章还没有来得及看 http://limboy.me/tech/2016/03/10/mgj-components.html 蘑菇街的实现,虽然蘑菇街不是一线的互联网公司,但是关于路由我印象中他是第一个提出来的。 不管是不是有争议,能提出新见解就是进步,值得学习。

第一次在掘金上写东西,请多指教


https://www.xamrdz.com/mobile/4y71987361.html

相关文章: