Neulich hat mir ein Benutzer einen Fehler bezüglich eines Symbolleistenelements gemeldet, das deaktiviert wurde, als es aktiviert werden sollte. Der Validierungscode (vereinfacht zu Ihrem Vorteil) sah folgendermaßen aus:
%Vor% Ich habe ein paar Minuten gebraucht, um zu erkennen, dass -count einen 32-Bit unsigned int zurückgibt, während BOOL ein 8-bit signed char ist. In diesem Fall hatte someArray 768 Elemente, was bedeutete, dass die unteren 8 Bits alle 0 waren. Wenn der int bei der Rückkehr in einen BOOL umgewandelt wird, wird er in NO
aufgelöst, obwohl ein Mensch dies erwarten würde Die Antwort lautet YES
.
Ich habe seitdem meinen Code in return [someArray count] > 0;
geändert, jetzt bin ich neugierig, warum BOOL wirklich ein signierter Char ist. Ist das in irgendeiner Weise wirklich "besser", als dass es ein Int ist?
Die bisher gegebenen Antworten konzentrieren sich darauf, warum BOOL kein int ist. Diese Antwort ist ziemlich klar: Ein Char ist kleiner als ein Int, und als Objective-C in den 80er Jahren entwickelt wurde, war es immer gut, ein paar Bytes abzuschaben.
Aber Ihre Frage scheint auch zu fragen: "Warum ist BOOL eher unterzeichnet als nicht unterzeichnet?" Dafür können wir schauen, wo BOOL typedef'ed ist, in /usr/include/objc/objc.h
:
Also gibt es eine Antwort: Die Objective-C-Designer wollten nicht typef BOOL in char eingeben, weil auf einigen Systemen unter einigen Compilern (und denken Sie daran, dass Objective-C älter als ANSI C ist, also unterschieden sich C-Compiler), ein char wurde unterzeichnet, und unter einigen, unsigniert. Die Designer wollten, dass @encode(BOOL)
einen konsistenten Wert über Plattformen hinweg zurückgibt, sodass sie die signedness in typedef enthalten.
Aber das wirft immer noch die Frage auf: Warum nicht unterzeichnet, sondern unterschrieben? Ich habe dafür keine definitive Antwort; Ich stelle mir den Grund vor, dass sie sich für das eine oder andere entscheiden mussten und entschieden sich dafür, mit unterzeichnet zu gehen. Wenn ich weitere Vermutungen anstellen müsste, würde ich sagen, dass Ints standardmäßig signiert sind (das heißt, wenn sie keinen Signedness-Qualifier enthalten).
Rückschritt zu einfacheren Zeiten.
Der BOOL-Typ wurde zurückentwickelt, als die CPUs natürlich mit 8-Bit-Typen arbeiteten und selten auf 16 oder 32 Bits aufgefüllt wurden. Doch Speicher war knapp und ein 1 Bit in 4 Bytes zu stopfen würde tatsächlich einen merklichen Teil zusätzlichen Speichers essen.
Beachten Sie, dass BOOL wahrscheinlich vor C ++ 's _bool um eine ganze Weile vorausging (sie könnten ungefähr gleich alt sein. Wenn NeXT Objective-C gewählt hat, war C ++ ungefähr die gleiche Popularität.)
Eine offensichtliche Antwort ist, dass es vier Mal kleiner ist (bei typischen 32-Bit- und 64-Bit-Architekturen) und auch keine Ausrichtungsanforderungen hat.
Ein boolescher Wert erfordert nur ein einzelnes Bit (0 oder 1), jedoch verwenden Standardsysteme Bytes als kleinste Einheit. Ein Bool, das als ein Byte dargestellt wird, ist bei 8 Bits 4 mal kleiner als eine 32-Bit-Ganzzahl, daher die Motivation für Byte über Ganzzahl.
Bools sind nützlich, um ein wenig Platz zu sparen und den Wert auf 0 oder 1 zu beschränken. Es ist ein kleinerer Typ aus demselben Grund, aus dem Sie einen Float über einen Double oder einen Short über einen Long verwenden. Nur Platz Bedenken.
Deshalb ist es eine gute Idee, mit Ihrem Casting explizit zu sein und im Falle eines booleschen Werts einen tatsächlichen logischen Vergleich zwischen zwei gleichen Typs durchzuführen, um einen tatsächlichen bool anstelle eines abgeschnittenen Werts zu berechnen. p>
Tags und Links objective-c