iOS 工程解耦后 消息传递方式

本文介绍了一种通过中央调度系统Bus实现跨业务模块间的消息传递机制。该机制利用BusObject进行注册与消息处理,解决了模块间相互依赖的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据上节的介绍,工程之间传递消息可以添加互相的依赖来实现,不过依赖所能解决的问题有一定的局限性,
如:Bu1 对Bu2 需要传递消息,可以添加Bu1对Bu2的依赖,但是如果同时Bu2对Bu1也要传递消息时,依赖就无法解决了,下面介绍一种更加系统的方法

注:这种方法只适用于上节介绍的解耦方法,其他的不一定适用,读者可以根据自己的需要使用

根据上节的介绍

main_project ————>Bu1
————>Business
main_project ————>Bu2

我们要做到main_project 、Bu1和Bu2之间传递消息,只有Business是所有的业务层都能使用到的,也是Bu和主工程传递消息的媒介。
在Business建立中央调度系统Bus

@interface Bus : NSObject


/**

 *  各业务BU注册busOjbect到总线,方便接收总线发起的调用

 *

 *  @param busObj     业务模块的busObject

 */

+ (void)register:(BusObject *)busObj;


/**

 *  数据总线,跨业务模块同步调用

 *

 *  @param binuessName   业务名

 *  @param param         调用所带参数,可变长参数,注意参数均为Object类型

 *

 *  @return 同步调用返回的结果

 */

+ (id)callData:(NSString *)buinessName param:(NSObject *)param, ... NS_REQUIRES_NIL_TERMINATION;

@end


@interface Bus()


@property (nonatomicstrongNSMutableDictionary *BusObjectMap;

//用于存放对外接口子系统的类关系


@end


static Bus *g_bus;


@implementation Bus


+ (void)initializeBusIfNeed {

    if (g_bus == NULL) {

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            g_bus = [[Bus allocinit];

        });

    }

}


+ (Bus *)sharedInstance {

    [Bus initializeBusIfNeed];

    return g_bus;

}


+ (BusObject *)busObjectForName:(NSString *)bizName {

    OSSpinLock spinLock = OS_SPINLOCK_INIT;

    OSSpinLockLock(&spinLock);

    

    NSDictionary *busObjectMap = [Bus sharedInstance].BusObjectMap;

    

    NSArray *hostList = [busObjectMap allKeys];

    NSString *findKey = nil;

    for (NSString *aKey in hostList) {

        if ([[bizName lowercaseStringhasPrefix:[aKey lowercaseString]])   {

            findKey = aKey;

            break;

        }

    }

    BusObject *busObj = [busObjectMap valueForKey:findKey];

    OSSpinLockUnlock(&spinLock);

    

    if (![busObj isKindOfClass:[BusObject class]]) {

        NSAssert(false@"找不到bizName:[%@]对应的busObject",bizName);

    }

    

    return busObj;

}


- (id)init {

    if (self = [super init]) {

        self.BusObjectMap = [NSMutableDictionary dictionary];

    }

    

    return self;

}


+ (void)register:(CTBusObject *)busObj {

    OSSpinLock spinLock = OS_SPINLOCK_INIT;

    OSSpinLockLock(&spinLock);

    if ([[Bus sharedInstance].BusObjectMap valueForKey:busObj.businessNamePrefixAndURLHost]) {

        NSAssert(false@"host=[%@]已注册,不可重复注册", busObj.businessNamePrefixAndURLHost);

    }

    [[Bus sharedInstance].dataBusObjectMap setValue:busObj forKey:busObj.businessNamePrefixAndURLHost];

    OSSpinLockUnlock(&spinLock);

}


+ (id)callData:(NSString *)bizName param:(NSObject *)param, ... NS_REQUIRES_NIL_TERMINATION {

    BusObject *busObj = [Bus busObjectForName:bizName];

    

    NSMutableArray *paramArr = nil;

    id eachItem;

    va_list argumentList;

    if (param != nil) {

        paramArr = [NSMutableArray array];

        

        [paramArr addObject: param];

        va_start(argumentList, param);

        while((eachItem = va_arg(argumentList, id))) {

            [paramArr addObject: eachItem];

        }

        va_end(argumentList);

    }

    

    id ret = [busObj doDataJob:bizName params:paramArr];

    return ret;

}


@end



在Bu1、Bu2和Main_Project中建立对外接口子系统
Main_Project有一个对外的MainBusObject
Bu1有一个对外的Bu1BusObject
Bu2有一个对外的Bu2BusObject

为了统一结构,所有的Bus子系统都需继承自BusObject

@interface BusObject : NSObject


@property (nonatomicreadonlyNSString *businessNamePrefixAndURLHost;


- (id)initWithHost:(NSString *)host;


/**

 *  数据总线,同步处理任务,需要子类重载

 *

 *  @param businessName 业务名

 *  @param params       参数列表,列表中参数类型为对象

 *

 *  @return 任务执行结果

 */

- (id)doJob:(NSString *)businessName

     params:(NSArray *)params;


@end



@interface BusObject() {

    NSString *bizNamePrefix;

    NSString *urlHost;

}


@end


@implementation BusObject


- (id)initWithHost:(NSString *)host {

    if (self = [super init]) {

        urlHost = [host lowercaseString];

    }

    return self;

}


- (NSString *)businessNamePrefixAndURLHost {

    return urlHost;

}


- (id)doJob:(NSString *)businessName params:(NSArray *)params {

    //TO BE OVERRIDE

    return NULL;

}


@end




当然需要在使用Bus之前把所有的子系统都注册入Bus系统

NSDictionary *busMap = @{    @“MainBusObject":@“main",

                              @“Bu1BusObject":@“bu1",

                              @“Bu2BusObject":@“bu2",

                            };

    

    [busMap enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

        BusObject *busObject = [[NSClassFromString((NSString *)key) allocinitWithHost:(NSString *)obj];

        [Bus register:busObject];

    }];



使用方法:

消息——传递—>Bus——分配—>BusObject——处理—>返回消息

我们为Bu1BusObject建立对象

#import "BusObject.h"


@interface Bu1BusObject : BusObject


@end


#import "Bu1BusObject.h"


@implementation Bu1BusObject


- (id)doJob:(NSString *)businessName params:(NSArray *)params {

    if ([businessName isEqualToString:@"bu1/hello"]) {

        NSLog(@"Hello");

    }

}


@end



在Bu2中只要

[CTBus callData:@“bu1/hello" param:nil]




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值