首页 > 解决方案 > Objective-C:将 IF 语句作为参数传递

问题描述

我需要将 IF 语句传递给方法。在 JavaScript 中,您可以将函数分配给变量。然后可以将该变量传递给函数并执行。这在Objective-C中存在吗?

这是我想实现的模式:

-(void)singleComparisonWith:(NSArray *)data
                 IndexBegin:(NSUInteger)indexBegin
                   IndexEnd:(NSUInteger)indexEnd
                  Threshold:(float)threshold {

    NSIndexSet *set1 = [self searchWithData:data
                                      Range:[self makeInspectionWithRange:indexBegin
                                                                      End:indexEnd]
                                     Option:NSEnumerationConcurrent
                                 Comparison:XXXXXXXXX];
// XXXXXXXXX is an IF statement that looks for value at an index above threshold
}

-(void)rangeComparisonWith:(NSArray *)data
                IndexBegin:(NSUInteger)indexBegin
                  IndexEnd:(NSUInteger)indexEnd
              ThresholdLow:(float)thresholdLow
             ThresholdHigh:(float)thresholdHigh {

    NSIndexSet *candidates = [self searchWithData:data
                                               Range:[self makeInspectionWithRange:indexBegin
                                                                               End:indexEnd]
                                              Option:NSEnumerationReverse
                                          Comparison:YYYYYYYYY];
// YYYYYYYYY is an IF statement that looks for value at an index above thresholdLow and above thresholdHigh
}

-(NSIndexSet *)searchWithData:data
                        Range:(NSIndexSet *)range
                       Option:(NSEnumerationOptions)option
                   Comparison:(id)comparison {

    return [data indexesOfObjectsAtIndexes:range
                                   options:option
                               passingTest:^(id obj, NSUInteger idx, BOOL *stop){
// Comparison is used here. Returns YES if conditions(s) are met.
                               }
            ];
}

编辑:

感谢@Charles Srstka,这是解决方案。

NSIndexSet *set1 = [self searchWithData:data
                                  Range:[self makeInspectionWithRange:indexBegin
                                                                  End:indexEnd]
                                 Option:NSEnumerationConcurrent
                             Comparison:BOOL^(id o) {
                                return ([o floatValue] > threshold);
                             }
                    ];


-(NSIndexSet *)searchWithData:data
                        Range:(NSIndexSet *)range
                       Option:(NSEnumerationOptions)option
                   Comparison:(BOOL(^)(id o))comparison {

    return [data indexesOfObjectsAtIndexes:range
                                   options:option
                               passingTest:^(id obj, NSUInteger idx, BOOL *stop){
                                   return comparison(obj);
                               }
            ];

该段没有错误。

谢谢您的帮助。

标签: objective-c

解决方案


您在 Objective-C 中想要的称为块语法。虽然肯定不是最好看的东西,也不是最容易记住的东西,但它会做你想做的事。

// declares a block named 'foo' (yes, the variable name goes inside the parens)
NSUInteger (^foo)(NSString *) = ^(NSString *baz) {
    return [baz length];
};

// now you can call foo like a function:
NSUInteger result = foo(@"hello world");

// or pass it to something else:
[someObject doSomethingWith:foo];

// A method that takes a block looks like this:
- (void)doSomethingWith:(NSUInteger (^)(NSString *))block;

这个站点是一个方便的“备忘单”,列出了在 Objective-C 中声明块的所有方法。你可能会经常提到它。我链接到的 URL 是一个更新的、工作友好的镜像。如果您考虑一下,我相信您可以猜出该站点的原始 URL。;-)

基本上,每当您^在 Objective-C 中看到 a 时,您就是在查看块声明。当然,除非您正在查看 XOR 操作。但通常它是一个块。

编辑:查看我链接到的站点,它说“作为方法调用的参数”。您需要使用该语法声明它,即

... comparison: ^BOOL(id o) {
    return ([o floatValue] > threshold);
}];

我知道这不是世界上最直观的语法,这就是为什么该站点可用作备忘单的原因。

此外,与您的问题无关,但 Objective-C 命名约定是以小写字母开头的参数标签;即range:, options:,comparison:而不是Range:, Option:, Comparison:.


推荐阅读