既然是组件间通讯,这里所说的组件就是业务组件。
跳转
实际就是控制器A跳转到控制器B,控制器B作为某个组件的一个入口。
我们使用的方式是Target-Action,用到了一个三方CTMediator
看图,为了简化我们假设某个组件只有一个控制器SecondViewController。
要想不引入SecondViewController而跳到该控制器且可以传值,我们还需要额外的两个类CTMediator+TASecondVC和Target_TASecondVC。
CTMediator+TASecondVC(负责传值和获取目标控制器)
这是一个CTMediator的分类,我们在跳到SecondViewController的时候需要使用此分类的方法,它的方法是暴露给其他组件调用者的。
Target_TASecondVC(负责传值和返回目标控制器)
这个类是CTMediator+TASecondVC需要用到的,它会返回我们要跳转的VC以及传值给该VC。这个类是不会暴露给其他组件调用者的。
使用
现在我们要跳转到SecondViewController
UIViewController * vc = [[CTMediator sharedInstance] secondVCWithName:@"我"];
if (vc) {
[self presentViewController:vc animated:YES completion:nil];
}
代码很简单,并且没有SecondViewController的出现,其中的secondVCWithName方法是CTMediator+TASecondVC分类中的方法,参数是我们传的值。
我们看下secondVCWithName:方法的具体实现:
- (UIViewController *)secondVCWithName:(NSString *)name{
NSMutableDictionary * parameters = [NSMutableDictionary dictionary];
parameters[@"name"] = name;
return [self performTarget:@"TASecondVC" action:@"SecondVC" params:parameters shouldCacheTarget:NO];
}
这个类虽然需要Target_TASecondVC的支持,但并没有引入该类,而是通过调用CTMedia的方法实现的,CTMedia中使用runtime来实现找到某个类并调用这个类的某个方法。其调用的方法就是- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget。
performTarget后的参数是方法调用类,action后的参数该要要调用的方法。
看Target_TASecondVC的具体实现。
- (UIViewController *)Action_SecondVC:(NSDictionary *)parameters{
SecondViewController * secondVC = [SecondViewController new];
secondVC.name = parameters[@"name"];
return secondVC;
}
注意:
你会发现target的参数是"TASecondVC",而我们的类名是Target_TASecondVC,action的参数是"SecondVC",而我们实际调用的方法名是Action_SecondVC。感觉类名少了"Target_",方法名少了·"Action_"这是因为CTMedia内部为类名和方法加了这两个前缀。
正向传值
正向传值就像我们前面介绍的直接把参数拼接在方法里就好了。
反向传值
反向传值我们需要利用到block回调,将block作为方法的一个参数。
这里列出CTMedia分类的方法和Target_类的方法
- (UIViewController *)thirdVCWithName:(NSString *)name callBack:(dispatch_block_t)callBack{
NSMutableDictionary * parameters = [NSMutableDictionary dictionary];
parameters[@"name"] = name;
parameters[@"callBack"] = callBack;
return [self performTarget:@"TAThirdVC" action:@"thirdVC" params:parameters shouldCacheTarget:NO];
}
- (UIViewController *)Action_thirdVC:(NSDictionary *)parameters{
ThirdViewController * thirdVC = [ThirdViewController new];
thirdVC.name = parameters[@"name"];
thirdVC.callBack = parameters[@"callBack"];
return thirdVC;
}
问题
传参的时候有硬编码
附上一个小demo供大家参考:https://github.com/yangguanghei/Media-demo