方法作为参数类型

时间:2016-03-11 13:52:21

标签: javascript objective-c arrays nsarray objective-c-blocks

我继续尝试从Objective-C学习JavaScript,我很好奇,如果在Objective-C中有一个方法可以使用参数类型。下面是findIndex()JavaStript函数的示例,该函数返回传递测试的数组中第一个元素的索引(作为函数提供)。如果这甚至可能,那么Objective-C实现的内容与块有什么关系呢?

如果我在NSArray上编写类类别,我将如何将块传递给方法并在其自身上执行该条件(NSArray)。如果不可能,我很想知道原因。

    var ages = [3, 10, 18, 20];

    function checkAdult(age) {
        return age >= 18;
    }

    function myFunction() {
        document.getElementById("demo").innerHTML = ages.findIndex(checkAdult);
    }

这是我在另一个可能有助于块语法的StackOverFlow问题上找到的一个有用的消息。我正在尝试实现的findIndex()函数的定义。

阻止语法

  1. 阻止作为方法参数 模板

    - (void)aMethodWithBlock:(returnType (^)(parameters))blockName {
            // your code
    }
    

    实施例

    -(void) saveWithCompletionBlock: (void (^)(NSArray *elements, NSError *error))completionBlock{
            // your code
    }
    
  2. 阻止作为方法参数 模板

    [anObject aMethodWithBlock: ^returnType (parameters) {
        // your code
    }];
    

    实施例

    [self saveWithCompletionBlock:^(NSArray *array, NSError *error) {
        // your code
    }];
    
  3. 阻止作为局部变量** 模板

    returnType (^blockName)(parameters) = ^returnType(parameters) {
        // your code
    };
    

    实施例

    void (^completionBlock) (NSArray *array, NSError *error) = ^void(NSArray *array, NSError *error){
        // your code
    };
    
  4. 阻止作为typedef 模板

    typedef returnType (^typeName)(parameters);
    
    typeName blockName = ^(parameters) {
        // your code
    } 
    

  5. FindIndex()定义

    Array.prototype.findIndex ( predicate [ , thisArg ] )

      

    注意谓词应该是一个接受三个参数的函数   返回一个可强制设置为布尔值true或false的值。   findIndex为数组的每个元素调用谓词一次   升序,直到找到谓词返回true的那一个。如果   找到这样的元素后,findIndex会立即返回索引   那个元素值。否则,findIndex返回-1。

2 个答案:

答案 0 :(得分:2)

Objective-C中的对应代码:

@implementation NSArray (MyExtension)

- (NSUInteger)findIndexWithPredicate:(BOOL (^)(id element, NSUInteger index, NSArray* array))predicate {
    NSUInteger result = NSNotFound;
    if (NULL != predicate) {
        for (NSUInteger i = 0; i < self.count; i++) {
            if (predicate(self[i], i, self)) {
                result = i;
                break;
            }
        }
    }
    return result;
}

@end

请注意,我已将默认返回值从-1更改为NSNotFound,因为索引是无符号的。

方法调用:

NSUInteger index = [@[@3, @10, @18, @20] findIndexWithPredicate:^BOOL(id element, NSUInteger index, NSArray *array) {
    return [element integerValue] >= 18;
}];

您可以避免在JavaScript第一个索引中定义的额外参数:

@implementation NSArray (MyExtension)

- (NSUInteger)findIndexWithPredicate:(BOOL (^)(id element))predicate {
    NSUInteger result = NSNotFound;
    if (NULL != predicate) {
        for (NSUInteger i = 0; i < self.count; i++) {
            if (predicate(self[i])) {
                result = i;
                break;
            }
        }
    }
    return result;
}

@end

NSUInteger index = [@[@3, @10, @18, @20] findIndexWithPredicate:^BOOL(id element) {
    return [element integerValue] >= 18;
}];

使用enumerateObjectsUsingBlock:方法

,无需编写自定义类别即可获得相同的结果
[@[@3, @10, @18, @20] enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([obj integerValue] >= 18) {
        *stop = YES;
        index = idx;
    }
}];

此外,可以使用块的替代方法,如C函数指针。但是块提供了更大的灵活性。

答案 1 :(得分:0)

我确实为鲍里斯制定了类似的解决方案:

1. String answer [X] -> answer [V]
2. answer=='y' [X] -> answer.equals("y") [V]
3. answer.equals("y") || answer.equals("Y") [V] -> answer.equalsIgnoreCase("y") [V]

4. if(medicine==2); [X] -> if (medicine == 2) [V]