告别映射表:一套协议搞定 iOS 组件化路由

频道:娱乐 日期: 浏览:438 作者:赵婉婷

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 实例,零注册、零映射。

3.3 > 路由封装:把“查找”做成一张网

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 塞进 UIApplicationopenURL: 就能远程触发组件,远端调用同理。