美文网首页
【Toki组件化】通信中间件 TKModule

【Toki组件化】通信中间件 TKModule

作者: TokiHunter | 来源:发表于2021-03-29 15:43 被阅读0次

一、介绍

组件化这件事,简单理解就是把不同的业务拆分成单独的项目去开发,组件之间可以出现引用关系,但不可以出现依赖关系。

由于组件是不可以依赖另一个组件的,这导致调用其他组件的对外接口成为了一件很麻烦的事,传统方案是使用字符串映射Selector,这种方案依赖字符串这个不稳定的Key,不但没有代码联想,还会导致很多难以预测的问题。
经过一些尝试,我发现了还有一种简单的方案。TKModule作为组件的中间件,各组件可以通过创建TKModule的分类实现对外接口,也通过TKModule去调用其他组件的对外接口

当然,这也会带来一些问题:

  1. 我在开发A组件的时候,不能依赖B组件,那么我的开发环境中就不存在B组件的对外接口,就没法去调用。
  • 解决方案:组件间不可以依赖,但是可以引用。如果B组件的对外接口已经声明、实现并发布,我可以在A组件的Demo的Podfile添加B组件。
  1. 我在开发A组件的时候,C组件的对外接口仅仅作出声明,尚未实现便发布了,这时在A组件中调用C组件的对外接口 便会导致崩溃。
  • 解决方案: 在TKModule替换
    - (NSMethodSignature*)methodSignatureForSelector:(SEL)selector;
    - (void)forwardInvocation:(NSInvocation *)invocation;
    的实现,使用户(组件使用者)调用未实现的接口时会执行一个空的实现,避免崩溃。
    此外,我也可以在A组件的Demo中,根据我的需要去实现这个接口。
  1. 我在开发A组件的时候,D组件尚发布,这时在A组件中如何调用D组件的接口。
  • 解决方案:遇到种情况我们可以在A组件中去声明想要引用的接口。

二、基础用法

  • 实现接口

//  TKModule+Account.h
//  TKMAccountModule

@interface TKModule (Account)

- (void)showLoginView;

@end
//  TKModule+Account.m
//  TKMAccountModule

@implementation TKModule (Account)

- (void)showLoginView {
    //展示登录界面
}
  • 调用接口

//  TKMInitializeEntrance.m
//  TKMInitializeModule

#import "TKMInitializeEntrance.h"

@implementation TKMInitializeEntrance

...

- (void)loginButtonTapped {    
    [[TKModule shared] showLoginView];
}

...

@end

三、补充用法

  • 在组件中声明其他组件的对外接口

//  TKModule+AccountRecharge.h
//  TKMAccountModule

#import "TKModule.h"

@interface TKModule (AccountRecharge)

- (void)showRechargeView;

@end
  • 在Demo中实现其他组件的对外接口

//  TKModule+Mock.m
//  TKMAccountModule-Example

#import <TKModule/TKModule.h>

@implementation TKModule (Mock)

- (void)showRechargeView {
    //展示充值页面
}

@end

四、代码

TKModule 地址

//  TKModule.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef void(^TKModuleUnrecognizedSelectorCallback)(SEL);

@interface TKModule : NSObject

@property (nonatomic, strong) TKModuleUnrecognizedSelectorCallback unrecognizedSelectorCallback;

+ (instancetype)shared;

@end

NS_ASSUME_NONNULL_END
//  TKModule.m

#import "TKModule.h"

#import <objc/runtime.h>

@implementation TKModule

#pragma mark - shared

+ (instancetype)shared {
    static id instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

#pragma mark - Unrecognized

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
    NSMethodSignature *signature = [super methodSignatureForSelector:selector];
    if (!signature) {
        if (self.unrecognizedSelectorCallback) self.unrecognizedSelectorCallback(selector);
        signature = self.voidSignature;
    }
    return signature;
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    if (![invocation.methodSignature isEqual:self.voidSignature]) {
        [super forwardInvocation:invocation];
    }
}

#pragma mark - util

- (NSMethodSignature *)voidSignature {
    return [self methodSignatureForSelector:@selector(unrecognizedSelectorBackUp)];
}

- (void)unrecognizedSelectorBackUp {
    
}

@end

相关文章

网友评论

      本文标题:【Toki组件化】通信中间件 TKModule

      本文链接:https://www.haomeiwen.com/subject/sajfhltx.html