组件化通讯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实现代码逻辑¶
-
runtime是一套底层的c语言api,runtime的作用
-
获取类的私有变量。
- 动态产生类,成员变量和方法。
- 动态修改类,成员变量和方法。
-
交换两个方法的实现(swizzle)。
-
NSInvocation和performSelector:<#(SEL)#> withObject:<#(id)#>,直接调用某个对象的消息
-
调用methodSignatureForSelector:方法,尝试获得一个方法签名,如果获取不到,则直接调用doesNotRecognizeSelector抛出异常。如果能获取,则返回非nil;创建一个NSInvocation并传给forwardInvocation:
-
@编译器指令 之一,返回一个给定类型编码为一种内部表示的字符串
-
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
#pragma clang diagnostic pop
-
提供给外部模块使用
-
创建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。