2012-06-05 18 views
7

Como uso las matrices NSInteger con frecuencia, escribí una categoría para NSArray (y una para NSMutableArray también) que agrega métodos como integerAtIndex :, arrayByAddingInteger :, etc. Los métodos se encargan de envolver/desenvolver el NSInteger en un objeto NSNumber.Enumeración rápida en una categoría NSArray para NSIntegers

Lo que me pregunto es si hay alguna forma de mejorar mi categoría para que pueda hacer una enumeración rápida en los NSIntegers. Me gustaría ser capaz de escribir:

NSArray* arrayOfIntegers; 
    . 
    . 
    . 

for(NSInteger nextInteger in arrayOfIntegers) 
    { 
    } 

... .así que "nextInteger" se saca del objeto NSNumber detrás de las escenas. ¿Puedo hacer esto?

Respuesta

4

dudo que hay una limpia manera de hacer esto con NSFastEnumeration, ya que en gran medida depende de la nextObject método.

Pero, se podría hacer de otra manera, mediante la adición de un método de bloques para ello:

@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 

De esta manera, se podría utilizar en su código de una manera similar:

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 

Quizás desee echar un vistazo al NSArray categories en el Lumumba Framework, que yo escribo: D

+1

Pedante: debe usar '-integerValue' si devuelve' NSIntger's. – Wevah

+0

Vaya, debe haberse confundido con JavaScript. Actualizado el código Gracias por la pista :) – Tharabas

+0

Tienes razón: no está muy limpio. Pero aún así, es mi solución preferida. Gracias. –

3

Esto no se puede hacer exactamente, pero puede convertir fácilmente su NSNumber en un NSInteger y usarlo más adelante. Incluso puede escribir una macro para ello:

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

usarlo como:

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

si realmente le gustan los bloques, pruebe esto:

@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); 
    }); 
} 

Tenga en cuenta que esta implementación depende del ARC.

Cuestiones relacionadas