Sometimes you want to enumerate both index and value in a NSArray. In Objective-C, there is a method on NSArray called enumerateObjectsUsingBlock:, which could solve this problem. We can even reuse some code since we could abstract the block and passing it here and there.

Take an artificial example, we want to calculate the sum of first three numbers in an array:

NSArray *arr = @[@1, @2, @3, @4, @5];
__block NSInteger result = 0;
[arr enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
    result += [num integerValue];
    if (idx == 2) {
        *stop = YES;
    }
}];

NSLog(@"%ld", result);
// Output: 6

Here we are using a terminating pointer *stop to control the loop. When it is placed at YES, the enumerating will be stopped. Since it is a pointer, in Swift it will be converted to a UnsafeMutablePointer<ObjCBool>. At the beginning, you may be surprised by this type and do not know how to deal with it. However, once you got familiar with these Unsafe pointers, you could know you can just set the memory of this pointer. The Swift code equivalent to Objective-C version would be:

let arr: NSArray = [1,2,3,4,5]
var result = 0
arr.enumerateObjectsUsingBlock { (num, idx, stop) -> Void in
    result += num as Int
    if idx == 2 {
        stop.memory = true
    }
}
print(result)
// Output: 6

Although it is very easy to use enumerateObjectsUsingBlock, it isn't an ideal method if we include the performance into consideration (here is a Fridy QA on this topic, and there seems no substantial change recently). Furthermore, this is a method of NSArray, instead of Swift Array. When we want to enumerate both indexes and values in Swift, we have a much better choice. By using the EnumerateGenerator, we can get a tuple containing both the element index and value:

var result = 0
for (idx, num) in enumerate([1,2,3,4,5]) {
    result += num
    if idx == 2 {
        break
    }
}
print(result)

So, I guess it is the time to say goodbye to enumerateObjectsUsingBlock:.