GLD_Mediator.m
5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//
// GLD_Mediator.m
// YX_BaseProject
//
// Created by yiyangkeji on 2018/4/9.
// Copyright © 2018年 com.yxvzb. All rights reserved.
//
#import "GLD_Mediator.h"
#import <objc/runtime.h>
@interface GLD_Mediator ()
@property (nonatomic, strong) NSMutableDictionary *cachedTarget;
@end
@implementation GLD_Mediator
+ (instancetype)shareMediaor{
static GLD_Mediator *mediaor;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mediaor = [[GLD_Mediator alloc]init];
});
return mediaor;
}
- (UINavigationController *)currentNavVc{
UITabBarController *tabbar = (UITabBarController *)[UIApplication sharedApplication].delegate.window.rootViewController;
return tabbar.selectedViewController;
}
- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)isShould{
Class targetClass;
NSObject *target = self.cachedTarget[targetName];
if (target == nil) {
targetClass = NSClassFromString(targetName);
target = [[targetClass alloc]init];
}
if (target == nil) {
//可根据开发设置默认处理
return nil;
}
SEL action = NSSelectorFromString(actionName);
if (isShould) {
self.cachedTarget[targetName] = target;
}
if ([target respondsToSelector:action]) {
return [self safePerformAction:action target:target params:params];
}else{
//如果是swift 对象
action = NSSelectorFromString([NSString stringWithFormat:@"Action_%@WithParams:", actionName]);
if ([target respondsToSelector:action]) {
return [self safePerformAction:action target:target params:params];
}else{
SEL act = NSSelectorFromString(@"notFound:");
if ([target respondsToSelector:act]) {
return [self safePerformAction:act target:target params:nil];
}else{
[self.cachedTarget removeObjectForKey:targetName];
return nil;
}
}
}
}
#pragma mark - private methods
- (id)safePerformAction:(SEL)action target:(NSObject *)target params:(NSDictionary *)params{
/**
调用方法的两种方式:
1,performSelector: withObject: 方法。 此方法只能传一个参数
2,NSIvocation 方法调用。此方法能传多个参数
*/
// 创建一个函数签名,这个签名可以是任意的,但需要注意,签名函数的参数数量要和调用的一致
NSMethodSignature *sig = [target methodSignatureForSelector:action];
if(sig == nil)return nil;
const char *type = sig.methodReturnType;
id value;
// strcmp 返回值为 相等
if (strcmp(type, @encode(void)) == 0) {
//根据方法签名生成
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
//设置消息调用者
[invocation setTarget:target];
//设置调用消息
[invocation setSelector:action];
//设置消息调用参数 从2开始是因为0和1分别target和action 占用
[invocation setArgument:¶ms atIndex:2];
//消息调用
[invocation invoke];
return nil;
}
if(strcmp(type, @encode(NSInteger)) == 0){
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
[invocation getReturnValue:&value];
return value;
}
if(strcmp(type, @encode(BOOL)) == 0){
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
[invocation getReturnValue:&value];
return value;
}
if(strcmp(type, @encode(CGFloat)) == 0){
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
[invocation getReturnValue:&value];
return value;
}
if(strcmp(type, @encode(NSUInteger)) == 0){
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
[invocation getReturnValue:&value];
return value;
}
//此方法是利用运行时给对象添加方法 此时编译器并不知道添加的方法是什么,这时候就会报错,这个宏就是忽略此报错的
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
//performSelector:withObject: 此方法不能返回基础数据类型对象(如:CGFloat等)
return [target performSelector:action withObject:params];
#pragma clang diagnostic pop
}
- (NSMutableDictionary *)cachedTarget{
if (!_cachedTarget) {
_cachedTarget = [NSMutableDictionary dictionary];
}
return _cachedTarget;
}
@end