在NSArray类别中实现快速枚举NSIntegers

7

由于我经常使用NSInteger数组,因此我为NSArray(和NSMutableArray)编写了一个类别,添加了integerAtIndex:,arrayByAddingInteger:等方法。这些方法负责在NSNumber对象中包装/取消包装NSInteger。

我的问题是是否有一种方法可以增强我的类别,以便我可以对NSIntegers进行快速枚举。 我想能够这样写:

NSArray* arrayOfIntegers;
    .
    .
    .

for(NSInteger nextInteger in arrayOfIntegers)
    {
    }

我可以这样做吗?使“nextInteger”从NSNumber对象中被提取出来。

3个回答

4

我怀疑使用NSFastEnumeration没有一种简洁的方式来完成这个操作,因为它严重依赖于nextObject方法。

但是,你可以通过添加一个块方法来以另一种方式完成它:

@interface NSArray (Integers)
-(void)eachInteger:(void(^)(NSInteger))block;
@end

@implementation NSArray (Integers)
-(void)eachInteger:(void(^)(NSInteger))block {
  for (NSNumber *num in self) {
    block(num.integerValue);
  }
}
@end

那么,您可以在您的代码中类似地使用它:
NSArray *arr = [NSArray arrayWithObjects:[NSNumber numberWithInt:23],
                                         [NSNumber numberWithInt:42],
                                         nil];
...
[arr eachInteger:^(NSInteger i) {
  NSLog(@"The int is %i", i);
}];
// =>
//    The int is 23
//    The int is 42

也许您会想要查看由我编写的Lumumba框架上的NSArray类别。请点击此处,链接指向NSArray类别源代码;或者点击此处,链接指向Lumumba框架主页。

1
过于追求细节:如果你要返回 NSInteger,应该使用 -integerValue - Wevah
糟糕,可能混淆了JavaScript。已更新代码。感谢提示 :) - Tharabas
你说得对:它并不是非常干净。但是,这仍然是我首选的解决方案。谢谢。 - Jay Slupesky
为了好玩,我试图实现一个NSEnumerator,它在idNSInteger之间进行了可怕的强制转换,但它实际上工作得非常好,但有一个主要缺点,你不能包含0作为范围,因为这将被解释为从nextObject返回nil :) - Mattias Wadman

3

确切地说,这是不可能做到的,但是您可以轻松地将NSNumber转换为NSInteger,然后稍后使用它。您甚至可以为此编写一个宏:

#define int_enum(var, arr, block) \
    for(NSNumber *__tmp in arr) { NSInteger var = [__tmp integerValue]; block }

使用方法:

NSArray *array = // whatever;
int_enum(counter, array, {
    // things you want to do with `counter' as an NSInteger
});

0
如果你真的喜欢块,可以试试这个:
@interface NSArray(blockIteration)

@property (copy, nonatomic, readonly) void (^forEachObject)(void (^block)(NSArray *, id));
@property (copy, nonatomic, readonly) void (^forEachInt)(void (^block)(NSArray *, int));
@property (copy, nonatomic, readonly) void (^forEachDouble)(void (^block)(NSArray *, double));

@end

@implementation NSArray(blockIteration)

-(void (^)(void (^)(NSArray *, id))) forEachObject
{
    return [^(void (^block)(NSArray *, id)) {
        block = [block copy];
        for (id obj in self)
        {
            block(self, obj);
        }
    } copy];
}

-(void (^)(void (^)(NSArray *, int))) forEachInt
{
    return [^(void (^block)(NSArray *, int)) {
        block = [block copy];
        for (NSNumber *num in self)
        {
            block(self, [num intValue]);
        }
    } copy];
}

-(void (^)(void (^)(NSArray *, double))) forEachDouble
{
    return [^(void (^block)(NSArray *, double)) {
        block = [block copy];
        for (NSNumber *num in self)
        {
            block(self, [num doubleValue]);
        }
    } copy];
}


@end

int main()
{
    NSArray *array = [NSArray arrayWithObjects:@"Hello", @"World", @"This", @"Is", @"A", @"Test", nil];

    array.forEachObject(^(id arr, id obj) {
        NSLog(@"%@", obj);
    });
}

请注意,此实现依赖于ARC。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接