先附上 coobjc 地址
今天先分析一下里面的一个实用功能点,如果有什么分析不对的勿怪。
当看到COPromise实用场景介绍的时候我会毫不犹豫的联想到bolts,
如果大家对bolts不熟悉的看一下(bolts Github)。
我先说一下应用场景介绍吧:
场景1.有一个界面中有3个接口A、B、C,界面在3个接口完成请求后再去对数据进行展示。
场景2.有一个界面中有3个接口A、B、C,接口C依赖接口A 和 B请求返回数据,完成所有接口请求后进行数据展示。
场景3.有一个界面中有3个接口A、B、C,接口 C依赖接口B 接口B 依赖A ,完成所有接口请求后进行数据展示。
以上场景想想是不是很难受,而且脑子里会出现线程操作。
下面我会根据场景进行代码的详细对比,主要是进行传统做法、bolts、coobjc 代码对比。
场景1具体描述 接口A 获取顶部banner 数据,接口B获取最新活动模板数据,接口C 获取猜你喜欢商品数据,3个接口请求完成后进行数据展示。
传统做法:
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//获取banner数据
[JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
dispatch_group_leave(group);
}];
});
dispatch_group_enter(group);
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//获取最新活动模板数据
[JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
dispatch_group_leave(group);
}];
});
dispatch_group_enter(group);
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//获取猜你喜欢商品数据
[JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
dispatch_group_leave(group);
}];
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//数据展示
[weakSelf reloadData];
});
bolts 方式:
//获取banner数据
-(BFTask *)searchInsBanner{
BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
[JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
[taskSource setResult:ayBanner];
}];
return taskSource.task;
}
//获取最新活动模板数据
-(BFTask *)searchNewMould{
BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
[JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
[taskSource setResult:ayMould];
}];
return taskSource.task;
}
//获取猜你喜欢商品数据
-(BFTask *)searchMould{
BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
[JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
[taskSource setResult:ayMould];
}];
return taskSource.task;
}
//调用方式
[[BFTask taskForCompletionOfAllTasksWithResults:@[[self searchInsBanner],[self searchNewMould],[self searchMould]]] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id _Nullable(BFTask * _Nonnull t) {
[weakSelf reloadData];
return nil;
}];
coobjc 方式:
//获取banner数据
-(COPromise *)fetchInsBanner{
COPromise *promise = [COPromise promise];
[JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
[promise fulfill:ayBanner];
}];
return promise;
}
//获取最新活动模板数据
-(COPromise *)fetchNewMould{
COPromise *promise = [COPromise promise];
[JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
[promise fulfill:ayMould];
}];
return promise;
}
//获取猜你喜欢商品数据
-(COPromise *)fetchMould{
COPromise *promise = [COPromise promise];
[JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
[promise fulfill:ayMould];
}];
return promise;
}
co_launch(^{
NSArray<JLBInsBannerModel *> *ayBanner = await([self fetchInsBanner]);
NSArray<JLBInsActivityModel *> *ayNewMould = await([self fetchNewMould]);
NSArray *ayMould = await([self fetchMould]);
[self reloadData];
});
结合以上提供的代码,我们分析其实在这个场景中bolts 和coobjc 的代码实现和可读性都很好,其实这个场景中个人还是推荐bolts的。
场景2具体描述 接口A 获取顶部banner 数据,接口B获取最新活动模板数据,接口C 获取猜你喜欢商品数据,接口C 依赖接口A 、B 返回数据然后进行请求,最后进行数据展示。
场景3也是这3个接口,但是B 依赖A、C依赖B,场景2在实用的时候,写法和逻辑一样按照场景3一样可以实现最终结果,那这里我就按照场景3来做对比了。
传统做法,用NSOperationQueue
//创建队列
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
//创建操作
NSBlockOperation *operation1=[NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"执行第1次操作,线程:%@",[NSThread currentThread]);
}];
NSBlockOperation *operation2=[NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"执行第2次操作,线程:%@",[NSThread currentThread]);
}];
NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"执行第3次操作,线程:%@",[NSThread currentThread]);
}];
//添加依赖
[operation1 addDependency:operation2];
[operation2 addDependency:operation3];
//将操作添加到队列中去
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
bolts 方式:
//获取banner数据
-(BFTask *)searchInsBanner{
BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
[JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
[taskSource setResult:ayBanner];
}];
return taskSource.task;
}
//获取最新活动模板数据
-(BFTask *)searchNewMould{
BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
[JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
[taskSource setResult:ayMould];
}];
return taskSource.task;
}
//获取猜你喜欢商品数据
-(BFTask *)searchMould{
BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
[JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
[taskSource setResult:ayMould];
}];
return taskSource.task;
}
//调用方式
[[[[self searchInsBanner] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
return [self searchNewMould];
}] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
return [self searchMould];
}] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
[weakSelf reloadData];
return nil;
}];
coobjc 方式:
//获取banner数据
-(COPromise *)fetchInsBanner{
COPromise *promise = [COPromise promise];
[JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
[promise fulfill:ayBanner];
}];
return promise;
}
//获取最新活动模板数据
-(COPromise *)fetchNewMould{
COPromise *promise = [COPromise promise];
[JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
[promise fulfill:ayMould];
}];
return promise;
}
//获取猜你喜欢商品数据
-(COPromise *)fetchMould{
COPromise *promise = [COPromise promise];
[JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
[promise fulfill:ayMould];
}];
return promise;
}
co_launch(^{
NSArray<JLBInsBannerModel *> *ayBanner = await([self fetchInsBanner]);
NSArray<JLBInsActivityModel *> *ayNewMould = await([self fetchNewMould]);
NSArray *ayMould = await([self fetchMould]);
[self reloadData];
});
你们没有看错这里coobjc 方式始终没有变,因为有await 你可以自由组合其执行顺序,感觉方便了很多,自己写上注释,那么业务代码逻辑一目了然。