您的位置:首页 > 移动开发 > IOS开发

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

2015-06-05 18:15 411 查看
根据上节的介绍,工程之间传递消息可以添加互相的依赖来实现,不过依赖所能解决的问题有一定的局限性,
如: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 (nonatomic, strong) NSMutableDictionary *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 alloc] init];
        });
    }
}

+ (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 lowercaseString] hasPrefix:[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 (nonatomic, readonly) NSString *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) alloc] initWithHost:(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]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: