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]
如: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]
相关文章推荐
- IOS 获取文本的高度和宽度
- E430(c) 修改版BIOS刷入攻略
- (转载)ios关闭虚拟键盘的几种方法
- IOS开发笔记(2)页面之间传递数据几种方式比较
- iOS推送 (百度推送)
- iOS常用快捷键
- iOS中的动画
- iOS 导出 ipa 包时 三个选项的意思
- IOS alpha导致subView也透明
- ios开发小技巧及经验积累
- IOS地图及定位使用
- iOS时间前后获取
- CoreData教学完整版(封装我们自己的CoreData工具)_Dylan
- IOS8 使用CLLocationManager定位服务问题
- ios项目打包,安装流程
- iOS开发多线程篇—自定义NSOperation
- 除了iOS 9还有很多 苹果WWDC 2015前瞻
- IOS代码注释小结
- iOS开发多线程篇—NSOperation基本操作
- ios8 xcode设置launchimage