Object-C BOOL深入探究

        這是一個很常見的類型-布爾,代表真或假的兩個狀態。但請注意,這裏寫的是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){
     ...
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章