告别映射表:一套协议搞定 iOS 组件化路由
01为什么组件化一定要“绕”在映射表上?
iOS 组件化已成标配,但 URLRoute、蘑菇街的 URL Block、Protocol-Class、Casa 的 Target-Action 四种主流方案,都绕不开“协议/URL 与组件映射”这张表。
写模板、做注册、维护字典,代码越写越臃肿;硬编码更是把宏定义、const 写满头文件,记忆成本高,编码效率低。
能不能把“映射”干掉,让组件即拿即用?下面这套 protocol-module 模式 给出答案。
02把“约定”写进代码里
Objective-C 的约定无处不在:init、copy、KVO 观察名前缀……我们把约定写死,就能省掉运行时查找。
核心思路一句话:协议名 + 后缀 = 接口类名,编译器帮你做“映射”。

上图把角色拆成三份:
用户(主 App):只关心协议,不关心实现。
商家(组件开发者):实现接口类,并返回服务体。
框架(router):按约定拿到接口类,实例化并返回。
03三步搭建 protocol-module
3.1 > 先写协议:让“怎么用”公开透明主 App 与组件之间,只需交换一份公开协议。
示例 BaseModule 协议:
```objc
@protocol BaseModule
(UIViewController *)serverBody;
@optional
(void)callback:(NSDictionary *)params;
@end
```
调用 ModuleA 时,再继承 BaseModule 并添加自定义字段:
```objc
@protocol ModuleA
@required
@property (nonatomic, copy) NSString name;
@end
```
3.2 > 组件实现:接口类命名有讲究组件开发者只需实现一个类,类名必须符合 “协议名 + SI” 格式,并遵守对应协议。
例如 ModuleA 的接口类:
```objc
@interface ModuleASI : NSObject
(UIViewController *)serverBody {
if (!serverBody) {
((OhgRacViewController )serverBody).interface = self;
}
return serverBody;
}
@end
```
.m 文件里只需返回一个 UIViewController 实例,零注册、零映射。
Router 类里只保留三个方法,其余全部交给编译器:
```objc
(instancetype)router;
(id)interfaceForProtocol:(Protocol *)p;
(id)interfaceForURL:(NSURL *)url;
```
核心逻辑一句:
```objc
(Class)_clsForProtocol:(Protocol *)p {
NSString clsString = [NSStringFromProtocol(p) stringByAppendingString:ModuleProtocol\_ServerInterface];
return NSClassFromString(clsString);
}
```
没有字典、没有缓存、没有硬编码,完全靠约定名称让编译器在编译期就完成“映射”。
单元测试阶段,若找不到接口类,直接抛异常,提示组件未实现。
04使用演示:一行代码调用组件
主 App 里完全不用关心组件内部实现,只需按协议传参:
```objc
(IBAction)showModule:(id)sender {
[OHGRouter router].showModuleAWithParams:@{ @"name": @"xiaobaitu" } callback:^(UIViewController vc) {
[self.navigationController pushViewController:vc animated:YES];
}];
}
```
整段代码里没有导入任何组件头文件,路由层也干净得像一张白纸——真正的“即插即用”。
调用格式统一为:协议名://参数,例如 ModuleA://?name=xiaobaitu。
把 URL 塞进 UIApplication 的 openURL: 就能远程触发组件,远端调用同理。