2012-09-11 94 views
6

Me gustan mucho los literales nuevos en Objective-C. Me pregunto si con las nuevas incorporaciones hay una mejor manera de comparar números.Comparación de NSNumber literales

Por ejemplo, si quiero comparar a y b:

a = @1; 
b = @2; 

es la única manera de comparar ellos de esta manera:

[a intValue] > [b intValue] 

o hay mejores y más elegantes, soluciones?

+0

Si lo desea, puede escribir una categoría agregando métodos como '[a greaterThan: b]' y '[a equalTo: b]' – pasawaya

+0

Es posible que la reescritura de los operadores eventualmente surja como una extensión de este número literal sintaxis. '@ 1' ya se convierte en' [NSNumber numberWithInt: 1] '- no hay ninguna razón para que' @ 1> @ 2' no pueda ser permitido y reescrito como '[@ 1 isGranterThan: @ 2]' (bueno, no hay razón aparte de una posible confusión: "¿Por qué no puedo hacer' if (1> @ 2) '?"). –

+0

sí, tienes razón, quitaría las comparaciones de punteros de bajo nivel ... pero siempre podrían hacer algo como @ 1 @> = @ 2 y luego implementar mayorThanOrEqualTo en NSNumber, por lo que se traduciría como [@ 1 greaterThanOrEqualTo: @ 2] ... de esta manera usted puede mantener su puntero aritmético así como las comparaciones lógicas – 0xSina

Respuesta

13

Para los cheques de igualdad, puede utilizar isEqualToNumber que comprueba si alguno de los contenidos id o es igual (con este último mediante compare):

if ([a isEqualToNumber:b])     // if a == b 

No estoy seguro qué se tampoco implementó los métodos de conveniencia isGreaterThanNumber y isLessThanNumber (y posiblemente >= y <= también), ya que el método compare a continuación parece un poco torpe.

Para los cheques de desigualdad, sólo tiene que utilizar compare directamente (también se puede hacer esto por la igualdad como puede verse en el primero de abajo):

if ([a compare:b] == NSOrderedSame)   // if (a == b) 
if ([a compare:b] == NSOrderedAscending) // if (a < b) 
if ([a compare:b] == NSOrderedDescending) // if (a > b) 

if ([a compare:b] != NSOrderedSame)   // if (a != b) 
if ([a compare:b] != NSOrderedAscending) // if (a >= b) 
if ([a compare:b] != NSOrderedSescending) // if (a <= b) 

Los detalles se pueden encontrar en la NSNumber class documentation page.


Tenga en cuenta que no hay nada que le impida la creación de su propia ayudante función que, por ejemplo, permitir que un código como:

if (nsnComp1 (a, ">=", b)) ... // returns true/false (yes/no) 

o:

if (nsnComp2 (a, b) >= 0) ... // returns -1/0/+1 

aunque es menos Objective-C y más C :-) Depende de si su definición de "elegante" está ligada principalmente por la eficiencia o legibilidad. Si es preferible a su opción intValue es una decisión que deberá tomar usted mismo.

+0

¡Demasiado rápido para mí! : D – Zhang

+0

Bueno, probablemente solo se agregue 'isEqualToNumber:' porque los métodos 'isEqualTo ...' se usan en muchos otros lugares [como 'isEqualToString:']. Sólo en mi humilde opinión. – Mazyod

+0

Gracias ... no sabía acerca de la comparación, pero aún no sabes> = o <= .... sería más increíble si lo hicieran @ 1 == @ 2 ... pero entiendo por qué no . – 0xSina

7

NSNumber implementa -compare: (al igual que varias otras clases). Por lo tanto se puede decir

switch ([a compare:b]) { 
    case NSOrderedAscending: // a < b 
     // blah blah 
     break; 
    case NSOrderedSame: // a == b 
     // blah blah 
     break; 
    case NSOrderedDescending: // a > b 
     // blah blah 
     break; 
} 
0

NSNumber también tiene un isEqualToNumber:

0

Aquí es el fragmento de código para comprobar que funciona bien:

NSLog(@"%d", number1 == number2); 
NSLog(@"%d", [number1 isEqual:number2]); 
NSLog(@"%d", [number1 isEqualToNumber:number2]); 

La salida:

1 
1 
1 

Conclusión:

Para comprender la comparación, debe comprender la asignación de instancias.NSNumber implementa internamente un caché de objetos asignados y asigna los objetos existentes a cualquier objeto recién creado utilizando valores. Si se encuentra un objeto NSNumber existente con el valor 1, no se crea una nueva instancia de NSNumber.