组件化
(说白了就是个解耦合的过程)
- 组件化的意义
适用于基础功能稳定,项目规模较大
项目变大,编译时间长,基础模块的产品间复用
多团队发布,集成,测试不便,协同开相互依跟冲突
- 组件化拆分
工具类,基础功能,基础UI控件,业务线
- 组件化通信选型
Target- Action
●抽离业务逻辑
●通过中间层进行调用
●中间层使用runtime反射
●中间层代码优化
URL Scheme
●使URL处理本地的跳转
●通过中间层进行注册&调用
●注册表无需使用反射
●非懒加载/注册表的维护/参数
Protocol-Class
增加 Protocol Wrapper层
中间件返回Protocol对应的Class
解决硬编码的问题
简单演示Target- Action
点击列表跳转到底层页解耦 内容页列表页
- 创建一个类 Mediator,所有类用这个作为中转
- 我们希望Mediator跟任何类也没有耦合
第一个类展示
__kindof UIViewController *detailController = [GTMediator detailViewControllerWithUrl:item.articleUrl];
中间代码
+ (__kindof UIViewController *)detailViewControllerWithUrl:(NSString *)detailUrl{
Class detailCls = NSClassFromString(@"GTDetailViewController");
UIViewController *controller = [[detailCls alloc] performSelector:NSSelectorFromString(@"initWithUrlString:") withObject:detailUrl];
return controller;
}
上面两个都是用字符串来反射出类 还有类的方法的
第一个类调用Mediator来解开跟Detali的耦合
然而中间代码又利用反射机制解开跟detail的耦合
我们再看一下
这个以对象作为参数向接收方发送消息的方法只能传递一个参数,有局限性
二是他使用NSString硬编码
在这里我们复习一下__kindof
kindof定义
instancetyp跟id详解
urlScheme
**
简单来说就是讲需要暴露出的detail注册到中间的dediator
**
中间层
typedef void(^GTMediatorProcessBlock)(NSDictionary *params);
+ (void)registerScheme:(NSString *)scheme processBlock:(GTMediatorProcessBlock)processBlock;
+ (void)openUrl:(NSString *)url params:(NSDictionary *)params;
注册
+ (void)load {
[GTMediator registerScheme:@"detail://" processBlock:^(NSDictionary * _Nonnull params) {
NSString *url = (NSString *)[params objectForKey:@"url"];
UINavigationController *navigationController = (UINavigationController *)[params objectForKey:@"controller"];
GTDetailViewController *controller = [[GTDetailViewController alloc] initWithUrlString:url];
// controller.title = [NSString stringWithFormat:@"%@", @(indexPath.row)];
[navigationController pushViewController:controller animated:YES];
}];
[GTMediator registerProtol:@protocol(GTDetailViewControllerProtocol) class:[self class]];
}
调用者
[GTMediator openUrl:@"detail" params:@{@"url":item.articleUrl,@"controller":self.navigationController}];
弊端很多不建议使用
Protocol-Class
在mediator中添加方法
//protol class
+ (void)registerProtol:(Protocol *)proto class:(Class)cls;//注册protocol跟class的关系
+ (Class)classForProtocol:(Protocol *)proto;//通过protocol返回class
实现方法
#pragma mark -
+ (NSMutableDictionary *)mediatorCache{
static NSMutableDictionary *cache;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cache = @{}.mutableCopy;
});
return cache;
}
@protocol GTDetailViewControllerProtocol <NSObject>
- (__kindof UIViewController *)detailViewControllerWithUrl:(NSString *)detailUrl;
@end
+ (void)registerProtol:(Protocol *)proto class:(Class)cls{
if (proto && cls) {//如果两个都不为空那么就通过协议来 跟class加入到字典里面
[[[self class] mediatorCache] setObject:cls forKey:NSStringFromProtocol(proto)];
}
}
+ (Class)classForProtocol:(Protocol *)proto{
//通过协议在字典里面寻找key
return [[[self class] mediatorCache] objectForKey:NSStringFromProtocol(proto)];
}
调用者
Class cls = [GTMediator classForProtocol:@protocol(GTDetailViewControllerProtocol)];
[self.navigationController pushViewController:[[cls alloc] detailViewControllerWithUrl:item.articleUrl] animated:YES];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:item.uniqueKey];
注册的人
[GTMediator registerProtol:@protocol(GTDetailViewControllerProtocol) class:[self class]];