.m
#import "ComponentScheduler+ModuleB.h" @implementation ComponentScheduler (ModuleB) - (UIViewController *)ModuleB_viewControllerWithCallback:(void(^)(NSString *result))callback { NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; params[@"callback"] = callback; return [self performTarget:@"ModuleB" action:@"viewController" params:params shouldCacheTarget:NO]; } @end我们发现这个分类实现非常的简单,就是对外暴露一个函数,然后执行[self performTarget:@"ModuleB" action:@"viewController" params:params shouldCacheTarget:NO]; ,并将执行的返回值返回出去。
这个分类的作用你可以理解为我们提前约定好Target的名字和Action的名字,因为这两个名字中间件组件中会用到。
上面的performTarget:action:params:shouldCacheTarget 函数是中间件提供的函数。因为ModuleBCategory 是 ComponentScheduler(中间件)的分类文件,所以可以调用到这个函数啦。
在ModuleBCategory 工程中需要引用到了中间件工程所以我们需要在ModuleBCategory 的Podfile文件中引用 中间件组件
示例代码如下:
# Uncomment the next line to define a global platform for your project platform :ios, '8.0' source 'https://github.com/CocoaPods/Specs.git' source 'https://github.com/guangqiang-liu/GQSpec.git' target 'ModuleB-Category' do # Uncomment the next line if you're using Swift or would like to use dynamic frameworks # use_frameworks! # Pods for ModuleB-Category pod 'ComponentScheduler' end第九步:
因为上面第八步中引用到中间件工程,这里我们就来看下中间件工程到底做了什么工作。还记得上面第八步中,我们调用了一个中间件提供的函数:performTarget:action:params:shouldCacheTarget吧,这个是中间件核心函数。
核心函数代码块如下:
还记得上面第八步中,我们调用这个函数传递的参数吧,我们在把调用代码拿过来看下
[self performTarget:@"ModuleB" action:@"viewController" params:params shouldCacheTarget:NO];
我们可以看到 TargetName 是我们传递的 ModuleB,action是我们传递的viewController,然后我们将 这两个参数传给了下面的函数:
[self safePerformAction:action target:target params:params];
我们来看下这两个参数的值具体是什么:
这个函数最终调用到苹果官方提供的函数:[target performSelector:action withObject:params];
看到 performSelector: withObject: 大家应该就比较熟悉了,iOS的消息传递机制。
[Target_ModuleB performSelector:Action_viewController withObject:params];上面这行伪代码意思是: Target_ModuleB这个类 调用它的 Action_viewController: 方法,然后传递的参数为 params。
细心的小伙伴们就会发现,我们没有看到过哪里有这个Target_ModuleB 类啊,更没有看到Target_ModuleB 调用它的 Action_viewController: 方法啊。
是的,这个Target_ModuleB类和类的Action_viewController方法就在第十步中讲解到。
第十步:
终于到了最后一步了,写的好艰辛,嗯,小伙们不要捉急,快了,快讲完了
细心的小伙们发现,我们上面讲的9步中,好像都没有提业务组件B的东西。是的,业务组件B除了提供组件B的业务功能外,业务组件B还需要为我们提供一个Target文件。
我们先来看下业务组件B的业务代码:
示例代码如下:
#import "ModuleBViewController.h" #import "PageBViewController.h" @interface ModuleBViewController () @end @implementation ModuleBViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.title = @"我是模块B业务组件"; self.view.backgroundColor = [UIColor whiteColor]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = CGRectMake(0, 0, 300, 100); btn.backgroundColor = [UIColor greenColor]; btn.center = self.view.center; [btn setTitle:@"模块B业务功能组件" forState: UIControlStateNormal]; [btn addTarget:self action:@selector(push) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; } - (void)push { PageBViewController *VC = [[PageBViewController alloc] init]; [self.navigationController pushViewController:VC animated:YES]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }我们发现,业务组件B的业务代码也很简单,就是做一个push 跳转操作,从PageA 控制器跳转到 PageB 控制器。 这个没有什么好讲的
我们再来看上面提到的target文件
示例代码如下: