CTMediator
一、原理
什么是RunTime?
RunTime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,
其中最主要的是消息机制, 消息(方法)传递,如果消息(方法)在对象中找不到,就进行转发
通过RunTime我们可以让一个对象
发送消息(也就是执行方法)、交换方法(Method Swizzling)、动态添加方法、给分类增加属性、字典转模型等
CTMetidor 主要用到就是RunTime中的让对象发送消息
//创建person对象
Person * p = [[Person alloc] init];
//调用对象方法
[p eat];
//本质:让对象发送消息
objc_msgSend(p,@selector(eat));
respondsToSelector
-(BOOL)respondsToSelector:(SEL)aSelector;
判断对象是否响应此方法,一般和performSelector 一起使用,防止crash
performSelector
performSelector 本质上就是会转化成 objc_msgSend 来进行实现,其内部实现步骤:
1、通过obj的isa指针找到它的 class ;
2、在 class 的 method list 找 eat ;
3、如果 class 中没到 eat,继续往它的 superclass 中找 ;
4、一旦找到 eat 这个函数,就去执行它的实现IMP 。
来看一下 CTMetidor 的一段代码:
- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget
{
if (targetName == nil || actionName == nil) {
return nil;
}
NSString *swiftModuleName = params[kCTMediatorParamsKeySwiftTargetModuleName];
// generate target
NSString *targetClassString = nil;
if (swiftModuleName.length > 0) {
targetClassString = [NSString stringWithFormat:@"%@.Target_%@", swiftModuleName, targetName];
} else {
targetClassString = [NSString stringWithFormat:@"Target_%@", targetName];
}
NSObject *target = [self safeFetchCachedTarget:targetClassString];
if (target == nil) {
Class targetClass = NSClassFromString(targetClassString);
target = [[targetClass alloc] init];
}
// generate action
NSString *actionString = [NSString stringWithFormat:@"Action_%@:", actionName];
SEL action = NSSelectorFromString(actionString);
if (target == nil) {
// 这里是处理无响应请求的地方之一,这个demo做得比较简单,如果没有可以响应的target,就直接return了。实际开发过程中是可以事先给一个固定的target专门用于在这个时候顶上,然后处理这种请求的
[self NoTargetActionResponseWithTargetString:targetClassString selectorString:actionString originParams:params];
return nil;
}
if (shouldCacheTarget) {
[self safeSetCachedTarget:target key:targetClassString];
}
if ([target respondsToSelector:action]) {
return [self safePerformAction:action target:target params:params];
} else {
// 这里是处理无响应请求的地方,如果无响应,则尝试调用对应target的notFound方法统一处理
SEL action = NSSelectorFromString(@"notFound:");
if ([target respondsToSelector:action]) {
return [self safePerformAction:action target:target params:params];
} else {
// 这里也是处理无响应请求的地方,在notFound都没有的时候,这个demo是直接return了。实际开发过程中,可以用前面提到的固定的target顶上的。
[self NoTargetActionResponseWithTargetString:targetClassString selectorString:actionString originParams:params];
@synchronized (self) {
[self.cachedTarget removeObjectForKey:targetClassString];
}
return nil;
}
}
}
action(SEL) 我们通过 NSSelectorFromString 获取了,
target 我们通过 NSClassFromString 获取,
接下来只需要通过 performSelector方法 执行 target(Class) 中的 action 即可。
[target performSelector:action withObject:params];
项目中的例子
1-CTMediator源码.png
2-检查版本更新.png
3-调用HPCenter的方法.png
项目结构图.png