Reputation: 10224
I'm still trying to get my head around how selectors and dynamic typing work in objective c. I'm essentially trying to implement this method (shown below in python/pseudocode, same thing really :P)
def isInArray(value, array, test):
for item in array:
if test(item) == value:
return True
return False
test = lambda obj: obj.property
My intended objective-c code was:
+ (BOOL)value:(id)value:
isInArray:(NSMutableArray *)array
usingSelector:(SEL)selector {
for (id item in array) {
if (value == [item selector]) {
return YES;
}
}
return NO;
}
However, this throws a compile error, complaining that I"m comparing two pointer types (id and SEL) in the if statement.
Shouldn't that if statement be comparing the object value with the object returned from running SEL selector on the object arritem? In other words, why does it think that it's comparing an object with a SEL (I don't see what would be returning a SEL there)
Upvotes: 1
Views: 2437
Reputation: 141879
Checkout performSelector
in NSObject
. The conditional would look like,
if (value == [item performSelector:selector])
By using Key Value Coding
(KVC), your code could become even simpler. Say you have an array named people
, where each person is an object of the class Person
. A Person
has firstName
and lastName
properties, and you want to get all people whose first name matches "John"
from the people
array. You could get an array of all first names, and then lookup the name "John"
in that array.
NSArray *firstNames = [people valueForKey:@"firstName"];
if ([firstNames containsObject:@"John"]) {
..
}
Even though we're using valueForKey
, it's actually making a call to the firstName
method, and not directly accessing the value.
Upvotes: 3
Reputation: 3980
at least one mistake I see in method definition. There are no need to add colon after variable name (in your case value
). And you should use performSelector:
to make object check with your selector.
+ (BOOL)value:(id)value
isInArray:(NSMutableArray *)array
usingSelector:(SEL)selector {
for (id item in array) {
if ([item performSelector:selector] == value) {
return YES;
}
}
return NO;
}
In some cases you will need use isEqualTo:
or isEqualToString:
(if you work with strings) instead of ==
because ==
will return true if it's the same object.
Also, if you will need just check presence of some object in NSArray, than you could use containsObject:
(return true if it is) and indexOfObjectPassingTest:
(return index of object or 'NSNotFound')
Upvotes: 0