web-dev-qa-db-ja.com

Objective-Cのbool、Boolean、BOOLに違いはありますか?

BOOLが実際にはsignedcharのtypedefであることは知っていますが、ブール値はどうですか?

Bool、Boolean、BOOLの違いは何ですか?

31
Frost

Booleanは古いCarbonキーワード(歴史的なMacタイプ)であり、unsigned charとして定義されています。 BOOLは、signed charとして定義されたObjective-Cタイプです。 boolは、_Bool標準Cタイプの定義済みバージョンです。 intとして定義されています。 BOOLを使用します。

編集(2019):Appleいくつかの 新しいドキュメントBOOLの基本的な実装について話します。基本的に、macOSではBOOLはまだ最終的にはsigned charですが、iOSおよび関連するプラットフォームでは、その下にあるネイティブC boolです。

47
Jon Shier

@JonShierの有用な答えを取り上げたくはありませんが、コメントに収まる以上に追加する必要があります...

bool

C99仕様で標準Cに導入されました。 (C99標準は1999年に公開されましたが、その後、広く使用されるようになるまでに数年かかりました。)それ以前は、「プレーン」Cは組み込みのブール型がないため、C上に構築されたライブラリは多くの場合独自に定義します。 (そして、C99コンパイラを採用した後でも、ソース/バイナリ互換性のために独自のタイプを使用し続けることがよくありました。)

ISO Cを作成していて、独自のブール型を持つ高レベルのライブラリのコンテキストで作業していない場合は、これを使用します。

Boolean

Carbon(さらに古いMac ToolboxからのOSX初期の互換性ブリッジ)によって定義されます。これは、一部のプロジェクトでまだ表示される可能性があります(実際には、非常に古いソースとの互換性のためにのみ存在するヘッダーの推移的な#includeのため)コード)。

これは使用しないでください。

BOOL

NeXTSTEPは1988年に独自のブール型を必要としていたため、ObjCによって定義されました。(オフィスの本棚にある最も古いobjc.hは1992年のもので、BOOLの定義が含まれています。)

ObjC BOOLはしばしばtypedef signed charとして定義されています。つまり、YES(1)やNO(0)よりも多くの値を保持できます。 注意しないと問題になる可能性があります 。 (なぜそうするのですか?タイプが1ビット幅の場合、パフォーマンスを向上させるために適切に配置されたメモリにパックするのは難しいためです。)

ただし、iOS 64ビット(tvOSを含む)およびwatchOSでは、コンパイラーはOBJC_BOOL_IS_BOOLを定義します。これにより、ObjC BOOLはC99boolの単なるエイリアスになります。つまり、言語/コンパイラは、ゼロ以外の値が常に1として格納されることを保証するため、typedef signed char BOOLに起因する問題は発生しません。 (ただし、macOSまたは32ビットiOSではまだ心配する必要があります。)

TLDR

ObjCフレームワーク(Cocoa、UIKitなど)を使用してObjCで作業している場合は、操作しているAPIとの一貫性を保つためにBOOLを使用する必要があります。 (その上、YESNOtruefalseよりもはるかに大きいので、絶対的な真実について話しているときは強調するのが良いでしょう。 ?)

3
rickster

新しいAPIが古いAPIと対話する必要がない場合、boolはBOOLよりも具体的で明確です。

Xcode 9を使用してMac以外のアプリケーションを構築する場合、BOOL v = 2; NSLog(@"%d", v);は「2」ではなく「1」を出力します。

Appleドキュメント への参照

0
DawnSong