「新しいタイプ」BOOL
(YES
、NO
)を見ました。
私はこのタイプがほとんどcharに似ていると読んだ。
テストのために:
NSLog(@"Size of BOOL %d", sizeof(BOOL));
NSLog(@"Size of bool %d", sizeof(bool));
両方のログに「1」が表示されることを確認してください(C++のboolはintで、sizeofが4である場合があります)
だから私は、boolタイプか何かに問題があるのではないかと思っていましたか?
速度を落とさずにbool(動作しているように見える)を使用できますか?
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)
したがって、はい、BOOLはcharであると仮定できます。 (C99)bool
型を使用できますが、AppleのObjective-CフレームワークとほとんどのObjective-C/CocoaコードはすべてBOOLを使用するため、BOOLを使用するだけでtypedefが変更されても頭痛の種はなくなります。
上記のように、BOOLは署名された文字です。 bool-C99標準(int)からの型。
ブール-はい/いいえ。 bool-true/false。
例を参照してください:
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");
そして結果は
リアルb1
REAL b2
NOT REAL b2
Bool!= BOOLであることに注意してください。以下の結果は一度だけ-REAL b2のみです
b2 = b1;
if (b2) printf("ONCE AGAIN - REAL b2 \n");
if (b2 != true) printf("ONCE AGAIN - NOT REAL b2 \n");
BoolをBOOLに変換する場合は、次のコードを使用する必要があります
BOOL b22 = b1 ? YES : NO; //and back - bool b11 = b2 ? true : false;
したがって、私たちの場合:
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");
それで..今何が得られますか? :-)
これを書いている時点では、これは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
つまり、64ビットiOSデバイスおよびWatchOS BOOL
はbool
とまったく同じですが、他のすべてのデバイス(OS X、32ビットiOS)ではsigned char
であり、コンパイラフラグ-funsigned-char
でオーバーライドすることさえできません。
また、このコード例はプラットフォームごとに異なる方法で実行されることを意味します(自分でテストしました)。
int myValue = 256;
BOOL myBool = myValue;
if (myBool) {
printf("i'm 64-bit iOS");
} else {
printf("i'm 32-bit iOS");
}
ところで、可能な値の約0.4%が負になるため、array.count
のようなものをBOOL
変数に割り当てることはありません。
使用すべきObjective-CタイプはBOOL
です。ネイティブのブールデータ型のようなものはありません。そのため、すべてのコンパイラでコードがコンパイルされるようにするには、BOOL
を使用します。 (Apple-Frameworksで定義されています。
うん、BOOLはobjc.hによる符号付き文字のtypedefです。
しかし、boolについては知りません。それはC++のことですよね? 1がYES/trueであり、0がNO/falseである符号付き文字として定義されている場合、どちらを使用しても問題ないと思います。
ただし、BOOLはObjective-Cの一部であるため、明確にするためにBOOLを使用する方がおそらく理にかなっています(他のObjective-C開発者は、使用中のboolを見ると困惑するかもしれません)。
BoolとBOOLのもう1つの違いは、キーと値の監視を行うとき、または-[NSObject valueForKey:]などのメソッドを使用するとき、同じ種類のオブジェクトに正確に変換しないことです。
誰もがここで言ったように、BOOLはcharです。そのため、charを保持するNSNumberに変換されます。このオブジェクトは、「A」や「\ 0」などの通常の文字から作成されたNSNumberと区別できません。元々BOOLだった情報を完全に失いました。
ただし、boolはCFBooleanに変換され、NSNumberと同じように動作しますが、オブジェクトのboolean Originは保持されます。
私はこれがブール対ブールの議論の議論だとは思わないが、これはいつかあなたを噛むかもしれない。
一般的に言えば、これはCocoa/iOS API(C99とそのネイティブbool型の前に設計された)のすべてで使用される型であるため、BOOLを使用する必要があります。
前述のように、BOOL
は、アーキテクチャによってはunsigned char
型であり、bool
はint
型です。簡単な実験で、BOOLとboolの動作が異なる理由を示します。
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);
驚いたことに、if(objcBOOL != YES)
はコンパイラによって1に評価されます。これはYES
が実際に文字コード1であり、コンパイラの観点からすると、文字コード64はもちろんnot equal文字コード1の場合、ifステートメントはYES/true/1
と評価され、次の行が実行されます。ただし、ゼロ以外のbool
型は常に整数値1に評価されるため、上記の問題はコードに影響しません。 Objective-C BOOL
型とANSI C bool
型を使用する場合の良いヒントを次に示します。
YES
またはNO
の値を割り当ててください。!!
演算子ではなくdoubleを使用してBOOL
型を変換します。YES
を確認するときはif(!myBool) instead of if(myBool != YES)
を使用しますが、not !
演算子を使用する方がずっときれいで、期待どおりの結果が得られます。ここで慣例に反します。 typedefの基本型が好きではありません。私はそれが価値を削除する役に立たない間接化だと思う。
また、特にビットマスクを使用する場合は、signed charへのキャストによるキャストの違いに注意してください。
bool a = 0x0100;
a == true; // expression true
BOOL b = 0x0100;
b == false; // expression true on !((TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH), e.g. MacOS
b == true; // expression true on (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH
BOOLがブールではなく符号付き文字である場合、BOOLへの0x0100のキャストは単にセットビットをドロップし、結果の値は0です。