У меня есть класс, который содержит коллекцию объектов. Я пытаюсь создать метод, который будет возвращать первый элемент коллекции, соответствующий предоставленному предикату.
Вот метод сбора:
...
//predicate is a boolean method that accepts an object as its single parameter
-(id<Notation>) getFirstChildMatching: (SEL) predicate declaredInInstance:(id) instance
{
NSMethodSignature *sig = [[instance class] instanceMethodSignatureForSelector:predicate];
NSInvocation *myInvocation = [NSInvocation invocationWithMethodSignature:sig];
[myInvocation setTarget:instance];
[myInvocation setSelector:predicate];
int numItems = childNotations.count;
for(int i=0;i< numItems;i++)
{
id<Notation> thisNotation = [childNotations objectAtIndex:i];
[myInvocation setArgument:thisNotation atIndex:2];
BOOL result =NO;
[myInvocation retainArguments];
[myInvocation invoke];
[myInvocation getReturnValue:&result];
if (result)
return thisNotation;
}
return nil;
}
Я создал тестовый класс, который тестирует этот метод.
Вот метод теста плюс предикат:
- (void) testGetFirstChildMatching
{
Leaf *line1 = [[Leaf alloc] initWithValue:1 step:Step_A andNumber:1];
Leaf *line2 = [[Leaf alloc] initWithValue:2 step:Step_B andNumber:2];
SEL mySelector = @selector(valueIs1:);
id<CompositeNotation> compositeNotation = [[CompositeNotation alloc] init];
[compositeNotation addNotation:line1];
[compositeNotation addNotation:line2];
id notation = [compositeNotation getFirstChildMatching: mySelector declaredInInstance:self];
STAssertEquals(YES, [notation isKindOfClass:[Leaf class]], @"Should be of type Leaf: %@", notation);
//Leaf *found = ((Leaf *)notation);
STAssertEquals([notation value], line1.value, @"Should have found line 1 with value 1: actual %i", [notation value]);
[line1 release];
[line2 release];
}
-(BOOL) valueIs1: (Leaf *) leaf
{
if (leaf.value == 1)
return YES;
return NO;
}
Я обнаружил, что в строке "if (leaf.value == 1)" я получаю "нераспознанный селектор, отправленный в класс". Что не имеет смысла, так это то, что отладчик может видеть свойство value и его значение, поэтому объект явно имеет этот выбор.
Есть идеи?
Кстати, Leaf реализует протокол записи