0%

OC反射+多态调用类方法

多态

多态指的是允许父类的指针指向子类的对象,当指针指向不同的子类对象时,给它发送同一个消息就会有不同的响应.

如下定义一个父类Animal和二个子类Dog,Cat.

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
@interface Animal : NSObject

- (void)run;

+ (void)bark;

+ (void)canClimb:(void(^)(BOOL can))blk;

@end

@implementation Animal

- (void)run
{
NSLog(@"%@ run", self);
}

+ (void)bark {
NSLog(@"%@ bark", self);
}

+ (void)canClimb:(void (^)(BOOL))blk {
!blk ?: blk(NO);
}

@end

...
@implementation Dog

- (void)run
{
NSLog(@"%@ run", self);
}

+ (void)bark {
NSLog(@"%@ bark", self);
}

+ (void)canClimb:(void (^)(BOOL))blk {
!blk ?: blk(NO);
}

@end

...

@implementation Cat

- (void)run
{
NSLog(@"%@ run", self);
}

+ (void)bark {
NSLog(@"%@ bark", self);
}

+ (void)canClimb:(void (^)(BOOL))blk {
!blk ?: blk(YES);
}

@end

接下来我们来个反射+多态:

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
NSArray *clsArr = @[@"Animal", @"Dog", @"Cat"];
for (NSString *clsStr in clsArr) {
Class cls = NSClassFromString(clsStr);
id obj = [cls new];
[obj run];
}

for (NSString *clsStr in clsArr) {
Class cls = NSClassFromString(clsStr);
[cls performSelector:@selector(bark)];
}

//手动写全
for (NSString *clsStr in clsArr) {
Class cls = NSClassFromString(clsStr);
[cls canClimb:^(BOOL can){
NSLog(@"%@ can climb:%d",cls, can);
}];
}

//使用performSelector
for (NSString *clsStr in clsArr) {
Class cls = NSClassFromString(clsStr);
[cls performSelector:@selector(canClimb:) withObject:^(BOOL can){
NSLog(@"%@ can climb:%d",cls, can);
}];
}

以上需要注意的是:

Xcode对于id类型调用实例方法,实例方法会有补全提示.对于Class类型调用类方法,类方法就没有补全提示,但你写全后也不会报错.

对于类方法的动态调用可以使用performSelector,也可以手动写全,这里Xcode不会自动补全不知道为什么.

觉得文章有帮助可以打赏一下哦!