iOS组件化组件间跳转通讯入门
常见的有三种:
1、URL Scheme
2、CTMediator(Target-Action)
3、Protocol-Class
案例:A页面通过这三种方式跳转B页面

那么我们需要创建是三个类:Mediator
AviewController
BviewController
1、URL Scheme
scheme是苹果系统提供的一种供APP之间跳转的机制,用来做组件间跳转也是可行的,这种做法是要全局维护一套scheme和block的映射表,在需要被调用的类(BviewController)中+(void)load
方法中注册并实现对应的block,在需要跳转的地方(AviewController)中通过URL来进行跳转并传值
实现:
//********Mediator.h中实现***********
@interface SJMediator : NSObject
//scheme跳转
typedef void(^processBlock)(NSDictionary *params);
+(void)registerScheme:(NSString *)scheme block:(processBlock)block;
+(void)openUrl:(NSString *)url params:(NSDictionary *)params;
@end
//********Mediator.m中实现***********
@implementation SJMediator
//维护的一套全局映射表(字典key:scheme,value:block),全局共用一个,所以使用单例
+ (NSMutableDictionary *)mediatorCache{
static NSMutableDictionary *cache;
static dispatch_once_t token;
dispatch_once(&token, ^{
cache = [NSMutableDictionary dictionary];
});
return cache;
}
//scheme注册,被跳转页面+(void)load中实现
+(void)registerScheme:(NSString *)scheme block:(processBlock)block{
if (scheme && block) {
[[[self class] mediatorCache] setObject:block forKey:scheme];
}
}
//跳转页面实现
+(void)openUrl:(NSString *)url params:(NSDictionary *)params{
//URL可能需要拆分出scheme进行使用,这里简单直接使用,默认URL就是单纯一个scheme
processBlock block = [[[self class] mediatorCache] objectForKey:url];
if (block) {
block(params);
}
}
@end
//********BviewController.m中实现***********
+ (void)load{
[SJMediator registerScheme:@"schemeJump://" block:^(NSDictionary *params) {
BviewController *vc = [[BviewController alloc] init];
UINavigationController *nav = params[@"nav"];
[nav pushViewController:vc animated:YES];
}];
}
//********AviewController.m中点击跳转方法中实现***********
NSDictionary *params = @{@"nav":self.navigationController};
[SJMediator openUrl:@"schemeJump://" params:params];

此种方法的总结:
1、需要维护一套映射表,并且注册方法写在+(void)load方法中,在main函数调用之前会走这个方法,会延长APP的启动时间
2、常驻内存,造成资源消耗
3、看似scheme,实则我们看代码中schemeJump://
我们可以随便换一个字符串都可以完成跳转,我们使用scheme是为了跟各端统一。用同一套规范就可以实现后端下发scheme,iOS和安卓两端都可以进行跳转
4、跳转的方式是在被跳转页面的load方法block中实现的,所以需要外部传参告诉跳转方式
5、传参方面通过scheme后面拼字符串形式,局限比较大,例如:schemeJump://?token=3jn23e&ID=01
2、CTMediator(Target-Action)
这种方式运用了苹果的运行时
实现:
//********Mediator.h中实现***********
@interface SJMediator : NSObject
//target-action方式
+ (__kindof UIViewController *)getBvcWithContent:(id)content;
@end
//********Mediator.m中实现***********
+ (__kindof UIViewController *)getBvcWithContent:(id)content{
Class cls = NSClassFromString(@"BviewController");
//对应的两个object是方法中的两个入参值,根据performSelector的方法来看,最多只能有两个参数,参数可以是任意类型,所以我们尽可能的用字典等集合类型来传参
UIViewController *vc = [[cls alloc] performSelector:NSSelectorFromString(@"initWithContent:color:") withObject:content withObject:[UIColor colorWithHexString:@"#FF0088"]];
return vc;
}
//********AviewController.m中点击跳转方法中实现***********
//通过target-action方式跳转详情页
UIViewController *vc = [SJMediator getBvcWithContent:@"target-action"];
[self.navigationController pushViewController:vc animated:YES];
//********BviewController.m中实现***********
BviewController中不需要实现其他额外的任何方法
只需要实现自己的initWithContent:color:方法

此种方法的总结:
1、不会入侵被跳转页面,被跳转页面不需要做任何处理
2、跳转方式由外部跳转方决定
3、硬编码多,对于类名和方法名一定要吻合,否则runtime获取不到类型和方法名就会报错,需要做防护处理
4、不需要维护全局映射表
5、传参方面通过字典传内容也相当多了
3、Protocol-Class
此方法与scheme类似,需要维护一个全局映射表(key:Protoc0l,value:Class)
实现:
//********Mediator.h中实现***********
@protocol BViewControllerProtocol <NSObject>
- (UIViewController *)jumpBvcWithParams:(NSDictionary *_Nullable)params;
@end
@interface SJMediator : NSObject
//protocol协议跳转
+ (void)registerProtocol:(Protocol *)protocol class:(Class)class;
+ (Class)fetchClassForProtocol:(Protocol *)protocol;
@end
//********Mediator.m中实现***********
@implementation SJMediator
+ (NSMutableDictionary *)mediatorCache{
static NSMutableDictionary *cache;
static dispatch_once_t token;
dispatch_once(&token, ^{
cache = [NSMutableDictionary dictionary];
});
return cache;
}
//protocol协议跳转
+ (void)registerProtocol:(Protocol *)protocol class:(Class)class{
if (protocol && class) {
[[[self class] mediatorCache] setObject:class forKey:NSStringFromProtocol(protocol)];
}
}
+ (Class)fetchClassForProtocol:(Protocol *)protocol{
Class cls = [[[self class] mediatorCache] objectForKey:NSStringFromProtocol(protocol)];
return cls;
}
@end
//********AviewController.m中点击跳转方法中实现***********
//通过protocol_class方式跳转详情页
Class cls = [SJMediator fetchClassForProtocol:@protocol(BViewControllerProtocol)];
NSDictionary *params = @{@"color":@"#550088"};
[self.navigationController pushViewController:[[cls alloc] jumpBvcWithParams:params] animated:YES];
//********BviewController.h中实现***********
注意:继承BViewControllerProtocol协议
//********BviewController.m中实现***********
+ (void)load{
//注册
[SJMediator registerProtocal:@protocol(BViewControllerProtocol) class:[self class]];
}
//实现协议方法,创建本类实例
- (UIViewController *)jumpVCWithParams:(NSDictionary * _Nullable)params {
NSString *colorStr = params[@"color"];
UIViewController *vc = [[[self class] alloc] init];
vc.view.backgroundColor = [UIColor colorWithHexString:colorStr];
return vc;
}

此种方法的总结:
1、需要维护一套全局映射表(跟scheme类似)
2、跳转的方式由跳转方处理
3、多了一层protocol
4、传参方面可以传各种类型
本篇只是作为入门,了解三种方式是怎么实现解耦通讯的,通过案例,其实三种利弊也可以看出来,当然还有比较深层次分析的,看这里->组件化方案