這是一個很常見的類型-布爾,代表真或假的兩個狀態。但請注意,這裏寫的是BOOL(大寫字母),並非輸入有誤,Object-C中的布爾類型就是這個樣子的。如果順其自然的將BOOL按照bool使用,很可能就會出現意想不到的結果。
請看代碼:
bool b1 = true;
BOOL b2 = true;
bool b3 = 256; //0x100
BOOL b4 = 256; //0x100
if(b1) NSLog(@"b1 is true");
if(b2) NSLog(@"b2 is true");
if(b3) NSLog(@"b3 is true");
if(b4) NSLog(@"b4 is true");
你覺得會輸出什麼?
b1 is true
b2 is true
b3 is true
沒有輸出b4 is true,由此可見BOOL與bool不能完全同等對待。
爲了能更容易的理解Object-C中BOOL的用法,我們還是從最基本的if語句開始說明。
if
if是編程語言裏最基本一個符號,簡單的理解是表達式爲真時執行,表達式爲假時不執行。如果你是個JAVA程序員就要注意了,在c裏,if有另外一種執行方式。表達式非0則執行,表達式爲0則不執行。int, bool, char等類型的值都可以作爲if的表達式使用。
if和bool
這個應該很容易理解,也是最直接的使用方式,bool的值只有2個, true和false。這裏不再說明。
if和int
上面提到if的一個判斷原則是非0則執行,0則不執行。請看代碼
int a = 100;
int b = 0;
if(a)
NSLog(@"a執行");
if(b)
NSLog(@"b不執行");
輸出:
a執行
if和char
char是1個字節的數值,所以也可以作爲if的表達式使用。執行時,char首先被轉換成int然後才參與計算。char a = 100;
char b = 0;
if(a)
NSLog(@"a執行");
if(b)
NSLog(@"b執行");
輸出結果與int作爲表達式的完全相同:
a執行
Object-C裏的BOOL
BOOL與bool並非同一個對象。Object-C裏的BOOL是使用typedef重定義的char。
在頭文件objc.h中有這樣幾行代碼:
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#define OBJC_BOOL_DEFINED
#define YES (BOOL)1
#define NO (BOOL)0
更準確的說,BOOL是無符號char的類型重定義,可以使用BOOL這個名字代替signed char使用。下面又定義了個2個符號, YES和NO,這是2個字面量,可以在代碼中直接使用YES代替1, NO代替0。
按照Object-C的原則,BOOL類型的變量只應該取YES和NO兩個值。當YES(非0值)作爲if的表達式時,if代碼塊裏的代碼便會執行,反之,NO則不執行。BOOL a = YES;
BOOL b = NO;
if(a == YES){
NSLog(@"a==YES");
}
if(b == NO){
NSLog(@"b==NO");
}
if(a){
NSLog(@"a is true");
}
if(b){
NSLog(@"b");
}
輸出:
a==YES
b==NO
a is true
現在回顧文章開頭的例子
bool b3 = 256; //0x100
BOOL b4 = 256; //0x100
if(b3) NSLog(@"b3 is true");
if(b4) NSLog(@"b4 is true");
這裏有些奇怪,bool與BOOL即使不是同一種數據類型,但是賦予的值都是非0值,按理說if也應該認爲這是一個檢查通過的表達式。
其實,BOOL是signed char的重定義,char的長度是1個字節,而數字256的低8位全是0,被轉換成char後,char類型的變量就是0了(高位被丟棄)。所以最終作爲if表達式的值實際上是0。
建議的用法
Object-C使用signed char重定義爲BOOL的原因就不多研究了,可能爲了一套完整語言的規範或是移植性的原因吧。
最後建議,爲了規範程序裏的代碼,BOOL只應該使用YES和NO這2個值,而且在if語句的判斷中儘量使用下面的格式:
if(a == YES){
…
}
if(b == NO){
...
}