定义
用iOS开发环境来举例,IoC容器的核心功能负责对象创建、依赖查找和依赖注入,这些功能都需要借助运行时runtime的反射实现
使用protocol
在IoC容器中,就算通过反射可以创建Class 和instance,但是实际开发过程中还是有缺陷,因为还是不能很好地访问Class的属性与方法,这时候可以通过iOS的Protocol来访问。
例子
在IoC容器中,创建一个Class的Protocol,此Protocol声明了Class的所有方法和属性,然后在Class中实现此Protocol接口便可。
//
// ClassAProtocol.h
// IOCAdapter
//
#ifndef ClassAProtocol_h
#define ClassAProtocol_h
NS_ASSUME_NONNULL_BEGIN
@protocol ClassAProtocol <NSObject>
@property (nonatomic, copy) NSString *var;
- (void)testMethod;
+ (void)testClassMethod;
@end
NS_ASSUME_NONNULL_END
#endif /* ClassAProtocol_h */
#import <Foundation/Foundation.h>
#import <IOCAdapter/ClassAProtocol.h>
NS_ASSUME_NONNULL_BEGIN
@interface ClassA : NSObject <ClassAProtocol>
@property (nonatomic, copy) NSString *var;
- (void)testMethod;
+ (void)testClassMethod;
@end
NS_ASSUME_NONNULL_END
IoC容器 Class缓存
因为从IoC容器中获取Class的次数较为频繁,我们可以在容器中加入缓存功能。
@interface IOCCacheServiceDict:NSObject
+ (instancetype)sharedInstance;
- (Class) getClass:(NSString*) key;
- (void) addService:(NSString*) key implClass:(Class) implClass;
@end
@implementation IOCCacheServiceDict{
NSMutableDictionary *_dictServices;
NSRecursiveLock *_lock;
}
+ (instancetype)sharedInstance{
static dispatch_once_t onceToken;
static IOCCacheServiceDict* dict;
dispatch_once(&onceToken, ^{
dict = [[self alloc] init];
});
return dict;
}
- (instancetype)init{
self = [super init];
if (!self) {
return nil;
}
_dictServices = [NSMutableDictionary dictionaryWithCapacity:25];
_lock = [[NSRecursiveLock alloc] init];
return self;
}
- (Class) getClass:(NSString*) key{
[_lock lock];
Class cls = _dictServices[key];
[_lock unlock];
return cls;
}
- (void) addService:(NSString*) key implClass:(Class) implClass{
[_lock lock];
[_dictServices setValue:implClass forKey:key];
[_lock unlock];
}
@end
获取Class
Class IOCGetServiceClass(Protocol* protocol){
NSString* protocolName = NSStringFromProtocol(protocol);
Class cls = [[IOCCacheServiceDict sharedInstance] getClass:protocolName];
if (nil != cls){
return cls;
}
NSString *protocolSubffix = @"Protocol";
return IOCGetServiceClassWithProtocol(protocol, protocolName, protocolSubffix);
}
Class IOCGetServiceClassWithProtocol(Protocol* protocol, NSString* protocolName, NSString* protocolSubffix){
NSString *className = [protocolName hasSuffix:protocolSubffix] ? [protocolName substringToIndex:protocolName.length - protocolSubffix.length] : protocolName;
Class cls = NSClassFromString(className);
IOCRegisterServiceForStringProtocol(protocolName, cls);
return cls;
}
BOOL IOCRegisterServiceForStringProtocol(NSString* protocol, Class implClass){
if (nil == protocol || nil == implClass){
return NO;
}
if ([[IOCCacheServiceDict sharedInstance] getClass:protocol]) {
return NO;
}else{
[[IOCCacheServiceDict sharedInstance] addService:protocol implClass:implClass];
return YES;
}
}
获取 instance
id IOCGetServiceInstance(Protocol* protocol){
Class cls = IOCGetServiceClass(protocol);
id value = [cls new];
return value;
}
调用
在不同的模块中,可以通过以下方法,来访问其他模块的Class和Class的属性、方法。
[IOCGetServiceClass(@protocol(ClassAProtocol)) testClassMethod];
[IOCGetServiceInstance(@protocol(ClassAProtocol)) testMethod];
[IOCGetServiceInstance(@protocol(ClassAProtocol)) var];