Potrebbe non essere subito chiaro che in Objective-C il “tipo” BOOL non è in realtà un vero tipo booleano (che ammette 0 o 1). Si tratta di un retaggio del linguaggio C originale, che non ha un tipo intrinseco booleano (il compilatore iPhone GCC C supporta ISO C99 che definisce un tipo bool).
Per chiarire, nel file di sistema di intestazione objc.h si può vedere quanto segue:
[code lang=”obj-c”]typedef signed char BOOL;[/code]
Da questo è chiaro che BOOL è realmente un tipo signed char. Questo ha alcune implicazioni quando cerchiamo di assegnare il “YES” e “NO” a valori che sono in genere assegnati alle variabili di “tipo” BOOL . Se guardiamo un po’ più in basso nel objc.h verrà visualizzato quanto segue:
[code lang=”obj-c”]#define YES (BOOL)1
#define NO (BOOL)0[/code]
Allora, qual è il problema con BOOL e YES? In poche parole, il problema è che le variabili di tipo BOOL possono contenere valori diversi da YES e NO. Al contrario di NO che non costituisce un problema poiché NO == 0 == NO , ma a confronto, per YES può essere difficile, soprattutto se si fa affidamento sul codice di terze parti. Considerate questo:
[code lang=”obj-c”]BOOL b = 37;
if (b) {
printf("b è YES!\n");
}
if (b != YES) {
printf("b non è YES!\n");
}[/code]
L’output potrebbe essere il seguente:
b è YES!
b non è YES!
Il problema sorge perché il confronto diretto con YES fallirà quando il valore di un tipo BOOL è diverso da zero e diverso da 1.
Si noti che ObjC (supponendo che l’impostazione predefinita C99 sia attivata) supporta anche il bool come tipo di dato, che è un tipo intrinseco booleano e può essere solo impostato su true o false. Un modo sicuro per la conversione tra BOOL e bool è il seguente:
[code lang=”obj-c”]
// da BOOL a bool
bool b = myBOOL ? true : false;
// e ritorno
myBOOL = b ? YES : NO;
[/code]
La morale della storia è quello di evitare i confronti diretti tra tipo BOOL e costanti YES.
Buon 2013!