2012-06-21 7 views
9

Voglio confrontare 2 valori BOOL in obiettivo-c.In Objective-c, un modo sicuro e valido per confrontare 2 valori BOOL?

Ho scoperto che (3) - (6) del codice seguente funziona.
(1) - (2) non funziona perché BOOL è solo signed char.

(3) funziona ed è molto leggibile ma penso che bool non sia obiettivo-c.
L'utilizzo di bool nel codice obiettivo-c è buono?

Qual è il modo sicuro e valido per confrontare 2 valori BOOL in obiettivo-c?
Ci sono altri modi migliori per confrontare?

BOOL b = YES; 
BOOL c = 2; 

NSLog(@"(1) %d", b == c); // not work 
NSLog(@"(2) %d", (BOOL)b == (BOOL)c); // not work 
NSLog(@"(3) %d", (bool)b == (bool)c); 
NSLog(@"(4) %d", !b == !c); 
NSLog(@"(5) %d", !!b == !!c); 
NSLog(@"(6) %d", (b != 0) == (c != 0)); 

risultati:

(1) 0 
(2) 0 
(3) 1 
(4) 1 
(5) 1 
(6) 1 
+7

'2' non è un' valore BOOL' valido; solo "SÌ" e "NO". Quello che stai facendo non è valido. – trojanfoe

+0

Il 4o metodo mi sembra buono. È breve e converte in modo sicuro il valore su 0 o su 1. – nhahtdh

+1

@trojanfoe: Il fatto è che Obj-C accetterà volentieri l'assegnazione del numero a BOOL, e con esso si può persino eseguire un'operazione bit a bit. – nhahtdh

risposta

5

È perfettamente valido utilizzare bool in Objective-C poiché fa parte dello standard C99 (§7.16). Secondo me è anche il modo migliore per gestire confronti sicuri di tipi booleani.

L'unico motivo per non utilizzare bool ovunque è che BOOL è onnipresente in Objective-C e nei framework.

+0

Uso 'bool' dappertutto tranne dove l'API Cocoa chiama' BOOL'. Una conversione sicura da una all'altra sarebbe (foo è bool e bar è BOOL): 'foo = bar? vero: falso; 'o' bar = pippo? SÌ: NO; ' – JeremyP

+0

grazie. pensavo che bool fosse C++. @JeremyP, perché 'foo = bar;' bar = pippo; 'non sono sicuri? –

+0

L'assegnazione di 'true' o' false' a 'BOOL' è valida e sicura. Lo standard dice che si espandono alle costanti intere '0' o' 1' (anche in §7.16). –

1

convertire il vostro numero per una valida BOOL, rispondendo che cosa si intende per "2"

nel vostro contesto, è 2 = YES

Int number = 2; 
BOOL c = (number == 2); //2 is YES 

è> 0 = SI

Int number = 2; 
BOOL c = (number > 0); //2 is YES 

Dipende virile su ciò che è vero e cosa è falso nell'applicazione

+1

Grazie. Cerco sempre di convertire in BOOL valido quando si assegna dopo aver appreso che i multipli di 256 sono convertiti implicitamente in 0 (NO). Ma è possibile che un metodo eseguito da un'altra persona restituisca un valore BOOL diverso da 0/1. E non converto il valore BOOL restituito in BOOL valido come 'b = !! [obj methodWhchReturnsBOOL];' Quindi, 'c = 2' può succedere. –

+0

Questo tipo di conversione non è necessario se si utilizzano correttamente BOOL. Se hai bisogno di pensarci, allora stai facendo qualcosa di fondamentalmente sbagliato. L'espressione (B && C) restituirà SÌ anche se c è 2 eb è 1. È possibile basare tutto il codice su questo tipo di espressioni, e questo è il modo corretto nell'algebra booleana. (questo è il motivo per cui si chiama BOOL/bool/Boolean) Vedi la mia risposta per riferimenti. –

1

Da objc.h:

typedef signed char  BOOL; 
.... 

#define YES    (BOOL)1 
#define NO    (BOOL)0 

A quanto pare, BOOL è signed char, quindi è vero che è possibile assegnare il numero di variabili del tipo BOOL, che rovinerà il confronto (dal momento che il confronto è un confronto tra interi).

Penso che il metodo (4) che utilizza la negazione per convertire il valore integrale arbitrario in 0 o 1 sia un buon modo breve per confrontare in modo sicuro il valore logico di 2 BOOL.

4

a parte le altre risposte, desidero notare che il confronto di bool per l'uguaglianza è non un'operazione molto comune. BOOL non è un tipo, è solo una macro che nasconde il fatto che i booleani sono solo numeri interi. Per ogni operazione booleana, è preferibile utilizzare strutture di programmazione e operatori in grado di gestire correttamente interi come booleani:

e.g: if (condition1 == NO) {} dovrebbe essere if (!condition1) {}

if (condition1 == condition2) {}
può essere
if ((condition1 && condition2) || (!condition1 && !condition2)) {}
o meglio
BOOL newCondition = (condition1 && condition2) || (!condition1 && !condition2); if (newCondition) {}

La via più breve per scrivere un condizione non deve essere il modo migliore.

+2

Non penso che il confronto tra valori booleani sia raro. Un caso comune è un setter per una proprietà BOOL con un ritorno anticipato shortcut: - (void) setAnimate: (BOOL) animate {if (_animate == animate) return; // else fa tutto il necessario per impostare o eliminare l'animazione} –

+5

Inoltre, per ragioni di correttezza: 'BOOL' non è una macro ma una typedef. –

+0

Grazie per la nota 'typedef'. Il _old value check_ è qualcosa di veramente speciale. Di solito, non ti interessa affatto il tipo di proprietà e non hai nemmeno bisogno di sapere che è un BOOL. – Sulthan

9

Il confronto di due valori booleani deve essere gestito con un'operazione XOR.

cercando di confrontare direttamente i due booleani è un uso improprio dei fondamenti della Algebra di Boole: http://en.wikipedia.org/wiki/Boolean_algebra_(logic)

Quando si sta facendo

BOOL a = (b == c); 

allora questo valore può restituire false anche se entrambi B e C sono veri Tuttavia, l'espressione b & & c restituirà sempre SÌ se entrambi b e c sono veri, vale a dire superiore a 0 e NO in caso contrario.

Invece questo è ciò che in realtà si sta cercando di fare:

BOOL xor = b && !c || !b && c; 
BOOL equal = !xor; 

equivalente con

BOOL equal = !(b && !c || !b && c); 

o

BOOL equal = (b && c) || (!b && !c) 

Se si deve spendere tempo fare in modo che il vostro BOOL i valori sono normalizzati (cioè impostati su 1 o 0), quindi stai facendo qualcosa di sbagliato.

+0

grazie jake! penso che tu e @Sulthan abbiate ragione. è bello ma è più lungo e meno leggibile/scrivibile di !! o (bool). perché c non ha l'operatore logico xor? La leggibilità di –

+2

può essere migliorata dai nomi delle variabili. Se ad esempio vuoi controllare se una persona è affamata ma non stanca o stanca ma non affamata, e hai due booletti che hanno lo stesso nome, allora l'espressione (affamata e \! Stanca) || (! hungry && tired) ha più senso dell'espressione (affamato! = stanco). (Come può la fame essere uguale a stanco, e cosa significherebbe?) –

+1

La quarta espressione nella domanda dell'OP risolve il problema in modo rapido e pulito. Si normalizzerà il numero su 0 o 1, quindi '==' si comporterà come XNOR (NON XOR). Altre espressioni (3 e 5, 6) sono anche corrette. – nhahtdh

-1

Se si assegna il numero intero 2 a una variabile di tipo BOOL, il codice è danneggiato. Qualunque cosa tu abbia dopo, è ciò che meriti.

Pertanto, l'unico modo ragionevole per confrontare due BOOL a e b è

if (a == b) ... 
if (a != b) ... 
+0

Direi che l'unico modo ragionevole sarebbe "if (a && b)" e "if (! A && b)", dato che questi operatori saranno in realtà delle vere operazioni booleane, mentre '==' e '! = 'sono operatori numerici. – vikingosegundo

Problemi correlati