Objective-C: BOOL vs bool
-
23-08-2019 - |
Frage
Ich sah die "neue Art" BOOL
(YES
, NO
).
las ich, dass diese Art fast wie ein Zeichen ist.
Für den Test habe ich:
NSLog(@"Size of BOOL %d", sizeof(BOOL));
NSLog(@"Size of bool %d", sizeof(bool));
Gut zu sehen, dass beiden Protokolle "1" angezeigt wird (manchmal in C ++ Bool ist ein int und seine sizeof 4)
So war ich frage mich nur, wenn es einige Probleme mit dem Bool Typ oder etwas sind?
Kann ich nur Bool (das scheint zu funktionieren), ohne Geschwindigkeit zu verlieren?
Lösung
Aus der Definition in objc.h
:
#if (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH
typedef bool BOOL;
#else
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif
#define YES ((BOOL)1)
#define NO ((BOOL)0)
Also, ja, können Sie davon ausgehen, dass BOOL ein Zeichen ist. Sie können die (C99) bool
Art verwenden, aber alle von Apples Objective-C-Frameworks und die meisten Objective-C / Cocoa-Code verwendet BOOL, so dass Sie selbst Kopfschmerzen sparen, wenn die typedef jemals nur mit BOOL ändern.
Andere Tipps
Wie oben erwähnt, BOOL ist ein signed char. Bool - Typ von C99-Standard (int).
BOOL - JA / NEIN. Bool - true / false.
Beispiele siehe:
bool b1 = 2;
if (b1) printf("REAL b1 \n");
if (b1 != true) printf("NOT REAL b1 \n");
BOOL b2 = 2;
if (b2) printf("REAL b2 \n");
if (b2 != YES) printf("NOT REAL b2 \n");
Und Ergebnis
REAL b1
REAL b2
NICHT REAL b2
Beachten Sie, dass bool! = BOOL. Ergebnis unten ist nur ERNEUT - REAL b2
b2 = b1;
if (b2) printf("ONCE AGAIN - REAL b2 \n");
if (b2 != true) printf("ONCE AGAIN - NOT REAL b2 \n");
Wenn Sie bool konvertieren BOOL sollten Sie nächsten Code verwenden
BOOL b22 = b1 ? YES : NO; //and back - bool b11 = b2 ? true : false;
Also, in unserem Fall:
BOOL b22 = b1 ? 2 : NO;
if (b22) printf("ONCE AGAIN MORE - REAL b22 \n");
if (b22 != YES) printf("ONCE AGAIN MORE- NOT REAL b22 \n");
Und so .. was wir jetzt bekommen? : -)
Zum Zeitpunkt des Schreibens ist dies die neueste Version von objc.h:
/// Type to represent a boolean value.
#if (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif
Es bedeutet, dass auf 64-Bit-iOS-Geräten und auf WatchOS BOOL
ist genau die gleiche wie bool
, während auf allen anderen Geräten (O X, 32-Bit-iOS) es signed char
ist und nicht einmal durch Compiler-Flag -funsigned-char
außer Kraft gesetzt werden
Es bedeutet auch, dass dieses Beispiel Code anders laufen auf verschiedenen Plattformen (getestet es selbst):
int myValue = 256;
BOOL myBool = myValue;
if (myBool) {
printf("i'm 64-bit iOS");
} else {
printf("i'm 32-bit iOS");
}
BTW zuweisen nie Dinge wie array.count
Variable BOOL
weil etwa 0,4% der möglichen Werte negativ sein wird.
Der Objective-C-Typ Sie verwenden sollten, ist BOOL
. Es gibt nichts, wie eine native boolean-Datentyp, also sicher sein, dass der Code kompiliert auf alle Compiler BOOL
verwenden. (Es ist definiert in dem Apple-Frameworks.
Yup, BOOL ist ein typedef für ein signed char nach objc.h.
Ich weiß nicht, über Bool, though. Das ist eine C ++ Sache, nicht wahr? Wenn es als signed char definiert ist, wobei 1 JA / true und 0 NO / falsch ist, dann stelle ich mir es nicht verwenden, welches Sie keine Rolle.
Da BOOL Teil von Objective-C ist, ist es jedoch wahrscheinlich mehr Sinn macht, eine BOOL für Klarheit zu verwenden (anderer Objective-C-Entwickler verwirrt werden könnte, wenn sie einen Bool in der Anwendung).
Ein weiterer Unterschied zwischen Bool und BOOL ist, dass sie konvertieren nicht genau auf die gleiche Art von Objekten, wenn Sie Schlüssel-Wert tun Beobachtung, oder wenn Sie Methoden wie - [NSObject ValueForKey:].
Wie jeder hier gesagt hat, ist BOOL char. Als solches wird es in einen NSNumber umgewandelt, um ein Zeichen zu halten. Diese Aufgabe ist nicht zu unterscheiden von einem NSNumber von einem regelmäßigen char wie ‚A‘ erstellt oder ‚\ 0‘. Sie haben völlig die Informationen verloren, die Sie ursprünglich eine BOOL haben.
Allerdings Bool ist mit einem CFBoolean umgewandelt, die die gleichen wie NSNumber verhält, aber die behält die boolean Ursprung des Objekts.
Ich glaube nicht, dass dies ein Argument in einem BOOL vs. Bool Debatte, aber das können Sie einen Tag beißen.
Generell sollten Sie mit BOOL gehen, da dies die Art überall in der Cocoa / iOS-APIs (entworfen, bevor C99 und seinen native Bool-Typ) verwendet wird.
Die akzeptierte Antwort wurde bearbeitet und seine Erklärung ein bisschen falsch geworden. Codebeispiel wurde aktualisiert, aber der Text bleibt gleich. Sie können nicht davon ausgehen, dass BOOL ein Zeichen für jetzt ist, da sie auf die Architektur und Plattform abhängt. Wenn Sie also Sie Code in 32-Bit-Plattform ausgeführt wird (zum Beispiel iPhone 5) und Druck @encode (BOOL) werden Sie „c“ sehen. Sie entspricht einer Typ char . Aber wenn Sie Sie Code auf iPhone 5s laufen (64 bit) Sie werden sehen, „B“. Sie entspricht einer Bool Typ .
Ich gehe gegen die Konvention hier. Ich weiß nicht typedef die auf Basistypen mögen. Ich denke, es ist eine nutzlose indirection, den Wert entfernt.
- Wenn ich den Basistyp in Ihrer Quelle sehen werde ich es sofort verstehen. Wenn es ein typedef ist ich habe es nachzuschlagen, um zu sehen, was ich wirklich bin den Umgang mit.
- Wenn auf einem anderen Compiler zu portieren oder das Hinzufügen eines weiteren Bibliothek ihren Satz von typedefs Fragen in Konflikt geraten und verursachen kann, die schwer zu debuggen sind. Ich habe gerade mit diesem in der Tat getan zu tun. In einer Bibliothek wurde boolean typedef int und in mingw / gcc ist es zu einem char typedef.
Wie oben erwähnt BOOL
könnte ein unsigned char
Typ auf Ihrer Architektur abhängig sein, während bool
vom Typ int
ist. Ein einfaches Experiment zeigt den Unterschied warum BOOL und Bool anders verhalten können:
bool ansicBool = 64;
if(ansicBool != true) printf("This will not print\n");
printf("Any given vlaue other than 0 to ansicBool is evaluated to %i\n", ansicBool);
BOOL objcBOOL = 64;
if(objcBOOL != YES) printf("This might print depnding on your architecture\n");
printf("BOOL will keep whatever value you assign it: %i\n", objcBOOL);
if(!objcBOOL) printf("This will not print\n");
printf("! operator will zero objcBOOL %i\n", !objcBOOL);
if(!!objcBOOL) printf("!! will evaluate objcBOOL value to %i\n", !!objcBOOL);
Zu Ihrer Überraschung if(objcBOOL != YES)
wird durch den Compiler zu 1 ausgewertet wird, da YES
tatsächlich der Zeichen-Code 1, und in den Augen der Compiler, Zeichencode 64 ist natürlich ungleich Zeichencode 1 damit die if-Anweisung evaluieren YES/true/1
und die folgende Zeile ausgeführt werden soll.
Da jedoch ein keine Nullen bool
Typ auswertet den ganzzahligen Wert immer 1 ist, wird die obige Frage nicht, Ihren Code bewirken. Im Folgenden sind einige gute Tipps, wenn Sie die Objective-C BOOL
Typ vs der ANSI C bool
Typ verwenden möchten:
- assign immer den
YES
oderNO
Wert und sonst nichts. - Konvertieren
BOOL
Typen durch die Verwendung von zwei nicht!!
Betreiber unerwartete Ergebnisse zu vermeiden. - Wenn für
YES
Verwendung Überprüfungif(!myBool) instead of if(myBool != YES)
es viel sauberer ist!
die nicht zu verwenden, Operator und gibt das erwartete Ergebnis.