定义一个protocol
,叫protocolB
,让BViewController
实现。
protocolB
里面可以定义BViewController
创建时需要的参数,例如这里的name
和age
。
@protocol ProtocolB <NSObject>
- (void)setBViewControllerName:(NSString *)name age:(int)age;
@end
BViewController
实现protocolB
#import "ProtocolB.h"
- (void)setBViewControllerName:(NSString *)name age:(int)age
{
self.nameText = name;
self.ageText = [NSString stringWithFormat:@"%d",age];
}
在router
里#import "ProtocolB.h"
,定义register
方法,将protocol和class对应起来,保存到字典protocol_class_map
@property(nonatomic, strong) NSMutableDictionary *protocol_class_map;
- (void)registerProtocol:(Protocol *)protocol forClass:(Class)cls;
在BViewController
里注册
// 如果在其他地方注册,必然要引入BViewController,造成耦合
[[Router shared] registerProtocol:@protocol(ProtocolB) forClass:BViewController.class];
在register
方法里将BViewController
和ProtocolB
关联,
在AViewController
里
#import "Router.h"
#import "ProtocolB.h"
[Router.shared push:@protocol(ProtocolB) param:@{@"name":@"zhangsan",@"age":@(18)}];
push
方法实现
- (void)push:(Protocol *)protocol param:(NSDictionary *)param
{
Class cls = self.protocol_class_map[NSStringFromProtocol(protocol)];
UIViewController<ProtocolB> *bViewController = [[cls alloc] init];
[bViewController setBViewControllerName:param[@"name"] age:[param[@"age"] intValue]];
[[self topViewController] pushViewController:bViewController animated:YES];
}
这段代码干的事:
1.通过协议ProtocolB
,找到对应的BViewController
类,创建实例
Class cls = self.protocol_class_map[NSStringFromProtocol(protocol)];
UIViewController<ProtocolB> *bViewController = [[cls alloc] init];
2.因为实现了协议,可以通过协议传入参数
[bViewController setBViewControllerName:param[@"name"] age:[param[@"age"] intValue]];
用一张图总结:
再总结:
我觉得最理想的router
是,只要AViewController
引入router
就可以跳转到BViewController
。
这里的操作是,ViewController
要有相应的protocol
,然后ViewController
要实现这个protocol
,然后ViewController
要注册protocol
和ViewController
的关联,因为要router
来注册,所以还要导入router
。
这里的router
还要导入protocol
。
router
通过导入每个ViewController
对应的Protocol
来避免导入具体的ViewController
,本质上,我觉得没有区别。
的确比较麻烦,不是很好的方案。