Object-C之(Null)與(Bool)

ningandjin發表於2014-04-05
在寫iOS程式的時候,想初始化一個空值的時候,經常會迷茫到底是用nil,null還是NSNull, 想定義一個布林值的變數時,又需要去想想應該用bool,BOOL抑或Boolean,賦值的時候應應該給YES/NO還是true/false。今天正好來理一下。

[size=large][b]nil/Nil/NULL/NSNull[/b][/size]

Matt Thompson總結了這4個變數的不同之處:
[table]
|Symbol| Value| Meaning|
|NULL| (void *)0| literal null value for C pointers|
|nil| (id)0 | literal null value for Objective-C objects|
|Nil| (Class)0| literal null value for Objective-C classes|
|NSNull| [NSNull null]| singleton object used to represent null|
[/table]

NULL是C語言中用來指代一個空指標的,Object-C是C語言的超集,可以使用C語言中特性,因此當你處於C語言語義下的時候應該使用NULL。比方說初始化一個結構體等
struct MyStruct *dStruct = NULL;


nil指代的是一個指向空的物件指標,因此當你初始化一個物件為空的時候,應該使用nil,另外,在java中,如果你去呼叫空物件的方法時,會丟擲NullPointerException,在obj-c中,會返回0。因此,在obj-c中,通常情況下是不需要去做空物件判斷的。即:

    if (obj !=nil && [obj isPass]) {
//do something
}
完全可以簡化為

if ([obj isPass]) {
//do something
}

Nil指代的是一個指向空的類指標,用的情況很少,當期望返回值為一個類的時候,空值應該使用Nil。

NSNull提供了一個類方法來生成一個單例的空物件, 這個類是由Foundation框架引入的,主要是為了繞過Obj-c中的集合類,NSArray,NSDictionary等不能放nil值的約束的。可以把其看做是一個可以用於集合類的nil的封裝。
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
mutableDictionary[@"Key-1"] = [NSNull null];
NSLog(@"Keys: %@", [mutableDictionary allKeys]);


[size=large][b]BOOL/bool/Boolean/NSCFBoolean[/b][/size]
Matt Thompson對這幾個變數的不同之處的歸納如下:
[table]
|Name| Typedef| Header| True Value| False Value|
|BOOL| signed char| objc.h| YES| NO|
|bool _Bool| (int)| stdbool.h |true |false|
|Boolean| unsigned char| MacTypes.h| TRUE| FALSE|
|CFBooleanRef| struct| CoreFoundation.h| kCFBooleanTrue| kCFBooleanFalse|
[/table]

簡單來說,在Obj-C中,都應該使用BOOL,然後使用YES和NO。這會幫你避免很多頭疼的問題,當你遇到問題的時候,比方說這個問題:[url]http://blog.bignerdranch.com/564-bools-sharp-corners/[/url]。
你可以通過上表中的差別,來定位問題。

相關文章