我有一个方法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对象
答案 0 :(得分:0)
选择器不保证方法实际存在于相关对象上。您可以获得选择器名称不存在于任何位置的编译器警告,但您不能确保它将在其将要使用的对象上存在。例如,这会编译:
[person performSelector: @selector(applicationDidBecomeActive:)]
即使您的应用代表存在applicationDidBecomeActive
而不是person
。
然而!通过编译器宏可以 这种事情。查看libextobjc库,它提供了您正在查找的选择器/密钥路径编译时间。这就是ReactiveCocoa中许多关键路径魔法的功能,但它也可以单独使用。