使用内联块在NSArray中搜索对象索引

时间:2012-06-11 12:22:43

标签: objective-c nsarray objective-c-blocks css

我已经看过几个使用NSArray indexOfObjectPassingTest的例子,但我无法使它们工作(它们不会返回有效的索引)。 所以现在我正在尝试使用内联块。我通过typedef一个块,然后将其设置为属性,合成它,并在构造函数中初始化它来完成它。 然而,这种方式使整个点变得无声,因为我可以轻松地创建一个方法并使用它(减少打字,减少工作量)。

我想要实现的是:

Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex: ^NSInteger (NSString *keyword){ 
    for (Observations *obs in self.myAppointment.OBSERVATIONS) {
        if ([obs.TIME isEqualToString:keyword] == YES) return (NSInteger)[self.myAppointment.OBSERVATIONS indexOfObject:obs];
    }
    return (NSInteger)-1;
}];

然而Xcode根本就没有它。我尝试过不同的变体,但是内联声明它似乎是一个问题,这很奇怪,因为正如我所说的那样,键入它,声明和合成它就像这样:

Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex:findObs(keyword)];

其中findObs又是一个定义的块,它执行相同的操作。 这是一个语法问题,还是我错过了其他更重要的东西?

3 个答案:

答案 0 :(得分:28)

-objectAtIndex:NSUInteger作为参数,但您传递的是一个块(由^表示)。您的第二个示例使用findObs参数调用keyword(可能是您的块),将该调用的结果传递给-objectAtIndex:

您可能希望将-objectAtIndex:-indexOfObjectPassingTest:结合使用:

NSString *keyword = /* whatever */;
NSArray *array = self.myAppointment.OBSERVATIONS;
NSUInteger idx = [array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop){ 
    Observations *obs = (Observations*)obj;
    return [obs.TIME  isEqualToString:keyword];
}];
if (idx != NSNotFound)
    Observations *obs = [array objectAtIndex:idx];

答案 1 :(得分:6)

这是一个返回字符串数组中字符串索引的示例。它可能适用于任何类型的物体。

NSString* myString = @"stringToFind";
NSUInteger objectIndex = [myStringArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return (*stop = ([obj isEqualToString:myString]));
    }];

准确回答原始问题:

NSString *keyword = @"myKeyword";
NSUInteger index = [self.myAppointment.OBSERVATIONS indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { 
    return (*stop = [(Observations*)obs.TIME  isEqualToString:keyword]);
}];
Observations *obs = (index!=NSNotFound) ? self.myAppointment.OBSERVATIONS[index] : NULL;

但将TIME与关键字进行比较...... ;)

这很奇怪

答案 2 :(得分:3)

没有必要键入def或合成任何东西来使你的第二个例子工作 - 只需从方法返回块,如下所示:

-(NSUInteger(^)(NSArray *, NSString *))findObs {
    return ^(NSArray *array, NSString *keyword) {
        for (NSUInteger i = 0; i < [array count]; i++) {
            Observations *obs = [array objectAtIndex:i];
            if ([obs.TIME isEqualToString:keyword]) {
                return i;
            }
        }
        return NSNotFound;
    };
}

Observations *obs = [self.myAppointment.OBSERVATIONS objectAtIndex:[self findObs](keyword)];

以下是一些good reasons for defining blocks as method return values, rather than inline