跳转至

组件化通讯Router

去model,传字符串(因为编译不会提示,为防止写错,字符串定义宏或常量)。

常规通讯

模块和模块之间通讯,耦合高。

模块A里面创建模块B,调用模块B里面的事务方法。

通讯解耦合

不直接引用头文件。模块之间的通讯通过引入一个中间层Mediator处理。

在A类中导入D类,创建D类这种形式不好。

因为直接引入有很强的依赖。为了解决依赖引入router路由。

通过router减少依赖,解耦。只需提供接口即可。

路由相当于中间层。有回调的话使用block参数。

路由用的命令模式。

命令模式/target-action

CTMediator

项目中所有的动作都是消息。消息主要是消息接收者和消息主体。

通过invocation可以配置target 和select。

发送者 接受者。

开关 电线 电灯。


为了简化我们假设某个组件只有一个控制器SecondViewController。 要想不引入SecondViewController而跳到该控制器且可以传值,我们还需要额外的两个类CTMediator+TASecondVC和Target_TASecondVC。

CTMediator+TASecondVC(负责传值和获取目标控制器)

这是一个CTMediator的分类,我们在跳到SecondViewController的时候需要使用此分类的方法,它的方法是暴露给其他组件调用者的。

Target_TASecondVC(负责传值和返回目标控制器)

这个类是CTMediator+TASecondVC需要用到的,它会返回我们要跳转的VC以及传值给该VC。这个类是不会暴露给其他组件调用者的。

Router文件

return [target performSelector:action withObject:para]; 

target是Target_TASecondVC,action是Target_TASecondVC文件中的方法。

外界只需要引入分类头文件,传值传参即可。

通讯:block传参。


Router实现代码逻辑

  1. runtime是一套底层的c语言api,runtime的作用

  2. 获取类的私有变量。

  3. 动态产生类,成员变量和方法。
  4. 动态修改类,成员变量和方法。
  5. 交换两个方法的实现(swizzle)。

  6. NSInvocation和performSelector:<#(SEL)#> withObject:<#(id)#>,直接调用某个对象的消息

  7. 调用methodSignatureForSelector:方法,尝试获得一个方法签名,如果获取不到,则直接调用doesNotRecognizeSelector抛出异常。如果能获取,则返回非nil;创建一个NSInvocation并传给forwardInvocation:

  8. @编译器指令 之一,返回一个给定类型编码为一种内部表示的字符串

  9. #pragma clang diagnostic push

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

#pragma clang diagnostic pop

  1. 提供给外部模块使用

  2. 创建podspec文件 pod spec create HHRouter

签名的作用:是否有返回值,参数。

类的创建在CTMediator层。

创建CTMediator分类,每个模块单独负责维护的对外接口。去中心化,不需要什么都让CTMediator去做。

Router使用的时候,使用url的形式。

url: http://xxx/模块名字/做一件事情/做事情的参数

router会提供很多方法,不止这一个。这些方法就是相当于接口。

别人写的私有的,我们看不到,所以会通过router方式,提供一个接口。自己来维护自己的router。

所以自己的库里面也应该有一个API文件夹,里面提供接口。创建OCTarget_Index文件,里面提供接口。

注:OCTarget_Index命名必须这样写,因为OCRouter文件里面是这样定义的。创建的类必须是OCTarger_开头,才能找到。里面的action必须以action_开头,

例:

appdelegate中tabbarcontroller的viewcontrollers设置,就需要返回一个nav。

提供的接口返回一个id类型。

BeeHive

面向协议 protocol-class

监听app进入后台前台,或者第三方都写在appdelegage里。很多地方都需要。

希望写一次处处可用。找一个接管appdelegage。