2010-11-09 14 views
6

Acabo de empezar a aprender Objective-C e hice una pequeña aplicación de brújula que mostrará una dirección cuando se trata de una variedad de títulos. Funciona muy bien, pero me pregunto si hay una forma más concisa de escribirlo usando NSRange. Después de mucho mirar, parece que NSRange se usa más para las funciones de cadena en lugar de números.¿Cómo puedo usar NSRange con enteros para simplificar mi código?

He intentado hacer una instancia de NSRange mi punto de partida para hacer esto más conciso, no pude localizar la función que encontraría si un número se encuentra dentro de un NSRange.

¿Estoy en el camino correcto aquí, o estoy haciendo esto más detallado de lo que debe ser?

Gracias de antemano ..

Aquí fue mi fallidos punto de partida para tratar de acortar el código:

// If heading falls within this range, then display "S" for south  
NSRange eastenRange = NSMakeRange (80, 100); 
NSRange southernRange = NSMakeRange (170, 190); 
etc... 

Aquí está mi código actual (funciona bien):

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateHeading:(CLHeading *)newHeading 
{ 
// Define and display the heading 
NSNumber *theHeading = [NSNumber numberWithInt:[newHeading trueHeading]]; 
[headingLabel setText:[NSString stringWithFormat:@"%@°", theHeading]]; 

// Define the range of directions 
NSNumber *northLowerRange = [NSNumber numberWithInt:10]; 
NSNumber *northUpperRange = [NSNumber numberWithInt:350]; 

NSNumber *eastLowerRange = [NSNumber numberWithInt:80]; 
NSNumber *eastUpperRange = [NSNumber numberWithInt:100]; 

NSNumber *southLowerRange = [NSNumber numberWithInt:170]; 
NSNumber *southUpperRange = [NSNumber numberWithInt:190]; 

NSNumber *westLowerRange = [NSNumber numberWithInt:260]; 
NSNumber *westUpperRange = [NSNumber numberWithInt:280]; 


// If the heading falls within the correct ranges, then display the direction 
if ([northLowerRange compare:theHeading] == NSOrderedDescending || [northUpperRange compare:theHeading] == NSOrderedAscending) 
    [directionLabel setText:@"N"]; 
else if ([eastLowerRange compare:theHeading] == NSOrderedAscending && [eastUpperRange compare:theHeading] == NSOrderedDescending) 
    [directionLabel setText:@"E"]; 
else if ([southLowerRange compare:theHeading] == NSOrderedAscending && [southUpperRange compare:theHeading] == NSOrderedDescending) 
    [directionLabel setText:@"S"]; 
else if ([westLowerRange compare:theHeading] == NSOrderedAscending && [westUpperRange compare:theHeading] == NSOrderedDescending) 
    [directionLabel setText:@"W"]; 
else 
    [directionLabel setText:@"-"]; 

} 

Respuesta

3

estoy haciendo esto más detallado de lo que debe ser?

Sí. Cuando desee realizar operaciones numéricas, evite NSNumber. La clase NSNumber existe solo porque las colecciones de Objective-C como NSArray, NSDictionary, etc. solo pueden contener objetos Objective-C. De lo contrario, se debe utilizar siempre llano o intNSInteger o CGFloat o double etc.

int heading = [newHeading trueHeading]; 
headingLabel.text = [NSString stringWithFormat:@"%d°", heading]; 

if (10 < heading || heading > 350) 
    directionLabel.text = @"N"; 
else if (80 < heading && heading < 100) 
    directionLabel.text = @"E"; 
// and so on. 

No es necesario utilizar NSRange.

+1

es generalmente mejor en Cocoa y Cocoa Touch para utilizar la arquitectura independiente de NSInteger y NSUInteger en lugar de int. – Chuck

+0

@Chuck: Correcto. Pero OP usa '+ numberWithInt:' así que guardo el 'int' en el código. – kennytm

+0

Gracias, @KennyTM. Mucho más limpio ahora. @Chuck - tomó su consejo sobre NSUInteger y lo usó también. Inicialmente usé numberWithInt: porque no arrojó una excepción, así que lo guardé. –

0

Un rango toma una ubicación y una longitud. Entonces, si quiere 80 a 100 grados para un rango oriental, puede usar NSMakeRange (80, 20). Eso crearía un rango que comenzaría en 80 grados, abarcando 20 grados.

9

Llegar tarde a la fiesta, pero el siguiente iba a funcionar y hacer uso de rangos creo:

NSRange easternRange = NSMakeRange (80, 20); 
NSRange southernRange = NSMakeRange (170, 20); 

NSInteger heading = 92; 
if (NSLocationInRange(heading,easternRange)) { 
    NSLog(@"Heading Easterly."); 
} else if (NSLocationInRange(heading,southernRange)) { 
    NSLog(@"Heading southerly."); 
} 

etc etc

0

Si estás interesado en una utilización más integrada de la estructura NSRange, he encontrado que es útil para comparar porciones de matrices:

NSRange aRange = NSRangeFromString([NSString stringWithFormat:@"{0:%d}",items.count]); 
NSIndexSet* aSet = [NSIndexSet indexSetWithIndexesInRange:aRange]; 
NSIndexSet *hasNotBeenReadSet = [items indexesOfObjectsAtIndexes:aSet 
                  options:NSEnumerationConcurrent 
                 passingTest: 
            ^BOOL(BasicItem* obj, NSUInteger idx, BOOL *stop) { 
            return [obj hasNotBeenRead]; 
            }]; 

int numberOfUnreadItems = hasNotBeenReadSet.count; 
Cuestiones relacionadas