使用另一个类的选择器以编程方式构建属性路径。这是如何运作的?

时间:2016-06-30 22:36:38

标签: objective-c key-value-observing

我有一个方法I,它采用可变数量的@selector()值并返回我在此站点上找到的正确的NSString。这在为我构建属性路径时很有用,因为我不喜欢为此使用字符串的想法,以及编译器能够检查路径构建的值的想法。方法是:

+(NSString *)keyPathFromSelectors:(SEL)firstArg, ...
{
    NSMutableArray *keys = [NSMutableArray array];

    va_list args;
    va_start(args, firstArg);

    for (SEL arg = firstArg; arg != nil; arg = va_arg(args, SEL))
    {
        [keys addObject:NSStringFromSelector(arg)];
    }

    va_end(args);

    return [keys componentsJoinedByString:@"."];
}

这很好用,但问题是:为什么?如果我在名为person的当前对象上有属性并且它有name,则路径显然为person.name,并且对我的方法的调用将如下所示:

+(NSSet *)keyPathsForValuesAffectingFoo
{
    return [NSSet setWithObject:[self keyPathFromSelectors:@selector(person), @selector(name),nil]];
}

name选择器(不应该)在我当前的类中技术上可见,它位于Person类中,我有一个参考,所以我如何访问正确的name SEL对象

1 个答案:

答案 0 :(得分:0)

选择器不保证方法实际存在于相关对象上。您可以获得选择器名称不存在于任何位置的编译器警告,但您不能确保它将在其将要使用的对象上存在。例如,这会编译:

[person performSelector: @selector(applicationDidBecomeActive:)]

即使您的应用代表存在applicationDidBecomeActive而不是person

然而!通过编译器宏可以 这种事情。查看libextobjc库,它提供了您正在查找的选择器/密钥路径编译时间。这就是ReactiveCocoa中许多关键路径魔法的功能,但它也可以单独使用。