KVC
测试代码如下
- (void) test
{
Animal *a = [Animal new];
Animal *b = [Cat new];
NSArray *arr = @[a, b];
NSArray *arr1 = [arr valueForKey:@"age"];
NSArray *arr2 = [arr valueForKey:@"run"];
NSLog(@"%@", arr1);
NSLog(@"%@", arr2);
}
@interface Animal : NSObject
@end
@interface Animal ()
@property (nonatomic, assign) NSInteger age;
@end
@implementation Animal
- (instancetype)init
{
self = [super init];
if (self) {
_age = 9;
}
return self;
}
- (void) run
{
NSString *result = [NSString stringWithFormat:@"%@ run", [self class]];
NSLog(@"%@", result);
// return result;
}
@end
@interface Cat : Animal
@end
@implementation Cat
- (instancetype)init
{
self = [super init];
if (self) {
[self setValue:@(11) forKey:@"_age"];
}
return self;
}
@end
打印结果是什么呢?
对一个集合发送消息,从自然语言的角度很明显是要集合中的每个元素都执行。比如:一班出列! 一班报年龄!
[classOne moveAhead]
[classOne age]
所以结果是:
2019-06-11 13:58:46.928727+0800 TestDemo[28183:950397] Animal run
2019-06-11 13:58:46.928843+0800 TestDemo[28183:950397] Cat run
2019-06-11 13:58:46.928962+0800 TestDemo[28183:950397] (
9,
11
)
2019-06-11 13:58:46.929049+0800 TestDemo[28183:950397] (
"<null>",
"<null>"
)
[arr valueForKey:@"run"]语句在执行的时候已经把方法run给执行了,arr2的值为两个null的数组,是消息执行完的结果,因为是void。我们把run方法换一下返回值试试
- (NSString *) run
{
NSString *result = [NSString stringWithFormat:@"%@ run", [self class]];
NSLog(@"%@", result);
return result;
}
打印结果如预期所想:
2019-06-11 14:04:42.858689+0800 TestDemo[28354:961129] Animal run
2019-06-11 14:04:42.858824+0800 TestDemo[28354:961129] Cat run
2019-06-11 14:04:42.858935+0800 TestDemo[28354:961129] (
9,
11
)
2019-06-11 14:04:42.859029+0800 TestDemo[28354:961129] (
"Animal run",
"Cat run"
)
再举个例子:
如何把一个NSArray *persons转化成一个NSDictionary,以Array中对象的x属性的值为key,以对象为value?
NSDictionary *dict = [NSDictionary dictionaryWithObjects: persons
forKeys:[persons valueForKey:@"x"]];
这就是高阶消息传递在OC中的一些应用,这个编程思想应用的地方还有很多,在不同的现代语言中,我们都能找到它的影子。