router浅析

router.png

背景

项目中有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 蘑菇街的实现,虽然蘑菇街不是一线的互联网公司,但是关于路由我印象中他是第一个提出来的。
不管是不是有争议,能提出新见解就是进步,值得学习。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容