先來看個stackOverflow上的例子:
if (nameTextField.text != (id)[NSNull null] || nameTextField.text.length != 0 ) {
NSString *msg = [[NSString alloc] initWithFormat:@"Hello, %@", txtName.text];
[lblMessage setText:msg];
}
結(jié)果:無論nameTextField.text 是否為空,都會進(jìn)入到if 條件句中。
錯誤在: nameTextField.text 如果為空米母,那么它 ==nil 而不是 (id)(NSNull null),所以無論如何,nameTextFiled != (id)[NSNull null] 都是true
我們先來看下這些空值的定義:
nil: Defines the id of a null instance,指向一個(實例)對象的空指針
例如:
NSString *msg = nil;
NSDate *date =nil;
Nil: Defines the id of a null class,指向一個類的空指針
例如:
Class class = Nil;
NULL:定義其他類型(基本類型腐巢、C類型)的空指針
char *p = NULL;
NSNull:數(shù)組中元素的占位符,數(shù)據(jù)中的元素不能為nil(可以為空玄括,也就是NSNull)冯丙,
原因:nil 是數(shù)組的結(jié)束標(biāo)志
如果用nil,就會變成
NSArray *array = [NSArray arrayWithObjects:
[[NSObject alloc] init],
nil,
[[NSObject alloc] init],
[[NSObject alloc] init],
nil];遭京,
那么數(shù)組到第二個位置就會結(jié)束胃惜。打印[array count]的話會顯示1而不是5
kCFNull: NSNull的單例
CoreFoundation 中有一段對 kCFNull的定義,實際上就是 NSNull 的單例
typedef const struct CF_BRIDGED_TYPE(NSNull) __CFNull * CFNullRef;
CF_EXPORT
CFTypeID CFNullGetTypeID(void);
CF_EXPORT
const CFNullRef kCFNull; // the singleton null instance
NSNull *null1 = (id)kCFNull;
NSNull *null2 = [NSNull null];
Talking is cheap ,show me the code!
NSLog(@"nil is %p",nil);
NSLog(@"Nil is %p",Nil);
NSLog(@"Null is %p",NULL);
NSLog(@"nil is %@",nil);
NSLog(@"NSNULL is %@",kCFNull);
nil is 0x0**
Nil is 0x0**
Null is 0x0**
nil is (null)**
NSNULL is <null>**
主要的區(qū)別就在 nil 系 和 NSNull系 的區(qū)別
nil : 作為對象的空指針和數(shù)組的結(jié)束標(biāo)志
NSNull:作為數(shù)組中的空值占位符
寫這篇文章我修改了好多次哪雕,隨著學(xué)習(xí)的深入船殉,有些早期的認(rèn)識是錯誤的八购俊?繁埂!!
例如這段代碼
Class class = nil;
Class class1 = Nil;
char *p =nil;
char *p1 = NULL;
NSString *str = NULL;
NSLog(@"nil is : %d",class==nil);
NSLog(@"nil is : %d",class==Nil);
NSLog(@"Nil is : %d",class1==nil);
NSLog(@"Nil is : %d",class1==Nil);
NSLog(@"integer is nil : %d",num == nil);
NSLog(@"integer is NULL : %d",num == NULL);
NSLog(@"integer is Nil : %d",num == Nil);
NSLog(@"nil equals Nil: %d",nil == Nil);
NSLog(@"Nil equals NULL:%d",p == p1);
NSLog(@"nil equals NULL: %d",nil == NULL);
結(jié)果全是1柒爵,所以這樣看法瑟,本質(zhì)上 nil , Nil 和 NULL 是一樣的
-->聰明的你能發(fā)現(xiàn)上面的錯誤碼窝剖???
看下下面這段說明
In Objective-C, it's important that you distinguish between objects and primitive types.
An **object** is always stored as a pointer, which is the object's location in memory. A pointer is just a number. With NSLog, you can use %p to see this value. You can display it in the debugger too, like this: print myObject. A pointer is displayed as a hexadecimal number, with a 0x
prefix. nil is essentially location zero (0x0000). When you allocate any kind of object, you'll get a pointer which isn't zero. When you assign an object to a variable, you are simply copying the memory address, not duplicating the object. With NSLog, you can use %@ to print out an object's description
. In the debugger, like this: print-object myObject
.
**Primitive types** like NSInteger
aren't objects. Instead of storing a pointer, usually you just store the value. When you assign an NSInteger
variable, you make a copy of the value. You can see the value in the debugger using print
. Or like this: NSLog("%ld", (long)currentRow)
. When you assign a primitive, you copy its value. Don't use %@
or print-object
with primitives — they expect objects.
參考:
1.http://blog.sina.com.cn/s/blog_5fb39f910101akm1.html
2.http://xiongzenghuidegithub.github.io/blog/2014/02/23/nil-nsnull-null-kcfnull/