2012-09-11 11 views
6

Mi piacciono molto i nuovi letterali in Objective-C. Mi chiedo se con le nuove aggiunte ci sia un modo migliore per confrontare i numeri.Confronto di letterali NSNumber

Per esempio, se voglio confrontare a e b:

a = @1; 
b = @2; 

è l'unico modo per confrontarli in questo modo:

[a intValue] > [b intValue] 

o ci sono migliori, più eleganti, le soluzioni?

+0

Se vuoi, puoi scrivere una categoria aggiungendo metodi come '[a greaterThan: b]' e '[a equalTo: b]' – pasawaya

+0

E 'possibile che la riscrittura del compilatore degli operatori alla fine emerga come un'estensione di questo numero letterale sintassi. '@ 1' diventa già' [NSNumber numberWithInt: 1] '- non c'è motivo per cui' @ 1> @ 2' non possa essere permesso e riscritto come '[@ 1 isGreaterThan: @ 2]' (beh, nessun motivo a parte la possibile confusione: "Perché non posso fare' if (1> @ 2) '?"). –

+0

sì hai ragione, toglierebbe i confronti di puntatori di basso livello ... ma potevano sempre fare qualcosa come @ 1 @> = @ 2 e quindi implementare greaterThanOrEqualTo in NSNumber, quindi sarebbe tradotto come [@ 1 greaterThanOrEqualTo: @ 2] ... in questo modo puoi mantenere il tuo aritmetico puntatore come pure i confronti logici – 0xSina

risposta

13

Per i controlli di uguaglianza, si può usare isEqualToNumber che controlla se sia il contenuto id o è uguale (con quest'ultimo utilizzando compare):

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

Non so perché hanno inoltre non ha implementato i metodi di convenienza isGreaterThanNumber e isLessThanNumber (e probabilmente anche >= e <=), dal momento che il metodo compare in basso sembra un po 'goffo.

Per i controlli di disuguaglianza, basta usare compare direttamente (si può anche fare questo per l'uguaglianza come si può vedere dalla prima sotto):

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) 

dettagli possono essere trovati sul NSNumber class documentation page.


Tenete a mente non c'è nulla impedisce di creare la propria funzione aiutante che, ad esempio, consentire il codice come:

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

o:

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

anche se è meno Objective-C e più C :-) Dipende se la tua definizione di "elegante" è legata principalmente all'efficienza o alla leggibilità. Che sia preferibile per l'opzione intValue è una decisione che dovrai prendere tu stesso.

+0

Troppo veloce per me! : D – Zhang

+0

Beh, probabilmente è stato aggiunto solo 'isEqualToNumber:' perché i metodi 'isEqualTo ...' sono usati in molti altri posti [come 'isEqualToString:']. Solo IMHO. – Mazyod

+0

Grazie ... non sapevo del confronto, ma ancora non sai> = o <= .... sarebbe più fantastico se lo facessero @ 1 == @ 2 ... ma capisco perché no . – 0xSina

7

NSNumber strumenti -compare: (come fanno un numero di altre classi). Così si può dire che

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 ha anche un isEqualToNumber:

0

Ecco il frammento di codice per verificare che funziona bene:

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

L'output:

1 
1 
1 

Conclusione:

Per capire il confronto, è necessario comprendere l'allocazione delle istanze.NSNumber implementa internamente una cache di oggetti assegnati e associa oggetti esistenti a qualsiasi oggetto appena creato utilizzando valori. Se viene trovato un oggetto NSNumber esistente con valore 1, non viene creata alcuna nuova istanza NSNumber.