如何基于属性值/如何使用选择器来确定对象是否在数组中?

时间:2012-01-06 08:55:54

标签: objective-c

我仍然试图了解目标c中选择器和动态类型的工作原理。我基本上试图实现这个方法(如下所示在python / pseudocode中,同样的事情真的:P)

def isInArray(value, array, test):
    for item in array:
        if test(item) == value:
            return True
    return False

test = lambda obj: obj.property

我的目标-c代码是:

+ (BOOL)value:(id)value:
    isInArray:(NSMutableArray *)array 
usingSelector:(SEL)selector {
    for (id item in array) {
        if (value == [item selector]) {
            return YES;
        }
    }
    return NO;
}

然而,这会引发编译错误,抱怨我在if语句中比较了两种指针类型(id和SEL)。

if语句是否应该将对象值与从对象arritem上运行的SEL选择器返回的对象进行比较?换句话说,为什么它认为它正在将一个对象与一个SEL进行比较(我没有看到什么会返回一个SEL)

2 个答案:

答案 0 :(得分:3)

NSObject中的结帐performSelector。条件似乎是,

if (value == [item performSelector:selector])

通过使用Key Value Coding(KVC),您的代码可能变得更加简单。假设您有一个名为people的数组,其中每个人都是类Person的对象。 Person具有firstNamelastName属性,您希望从"John"数组中获取名字与people匹配的所有人。您可以获取所有名字的数组,然后在该数组中查找名称"John"

NSArray *firstNames = [people valueForKey:@"firstName"];
if ([firstNames containsObject:@"John"]) {
  ..
}

即使我们使用valueForKey,它实际上是调用firstName方法,而不是直接访问该值。

答案 1 :(得分:0)

我在方法定义中看到的至少一个错误。变量名后不需要添加冒号(在您的情况下为value)。您应该使用performSelector:与选择器进行对象检查。

+ (BOOL)value:(id)value
    isInArray:(NSMutableArray *)array 
usingSelector:(SEL)selector {
    for (id item in array) {
        if ([item performSelector:selector] == value) {
            return YES;
        }
    }
    return NO;
}

在某些情况下,您需要使用isEqualTo:isEqualToString:(如果使用字符串)而不是==,因为==如果是同一个对象,则会返回true。

另外,如果你需要检查NSArray中某个对象的存在,那么你可以使用containsObject:(如果是,则返回true)和indexOfObjectPassingTest:(返回对象的索引或'NSNotFound')