1
nil:指向oc中对象的空指针
Nil:指向oc中类的空指针
NULL:指向其他类型的空指针,如一个c类型的内存指针
NSNull:在集合对象中,表示空值的对象
若obj为nil:
[obj message]将返回NO,而不是NSException
若obj为NSNull:
[obj message]将抛出异常NSException
2
nil和NULL从字面意思来理解比较简单,nil是一个对象,而NULL是一个值,我的理解为nil是将对象设置为空,而NULL是将基本类型设置为空的。而且我们对于nil调用方法,不会产生crash或者抛出异常。
看一下用法
NSURL *url = nil;
Class class = Nil;
int *pointerInt = NULL;
nil是一个对象指针为空,Nil是一个类指针为空,NULL是基本数据类型为空。
这五个概念很容易混淆,在一些场合下他们具有同样的用法。首先解释一下“空指针”意思,空指针是指该指针未指向一块有意义的内存区。如int *p; int *p = NULL;
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [NSNull null];
NSObject *obj3 = [NSObject new];
NSObject *obj4;
NSArray *arr1 = [NSArray arrayWithObjects:obj1, obj2, obj3, obj4, nil];
NSLog(@"arr1 count: %ld", [arr1 count]); //count: 3 因为obj=nil,在加入obj4时就结束添加对象
NSObject *obj1;
NSObject *obj2 = [[NSObject alloc] init];
NSObject *obj3 = [NSNull null];
NSObject *obj4 = [NSObject new];
NSArray *arr2 = [NSArray arrayWithObjects:obj1, obj2, obj3, obj4, nil];
NSLog(@"arr2 count: %ld", [arr2 count]); //count: 0,因为obj1=nil,所以后面的对象没有添加进去
[NSNull null]通常作为占位符作用,如下:
NSObject *obj1 = [NSNull null];
NSArray *arr1 = [NSArray arrayWithObjects:@"One", @"TWO", obj1,@"three",nil];
for (NSString *str in arr1) {
NSLog(@"array object: %@", str);
} //result:One、Two、、three
NSObject *obj1 = [NSNull null];
NSArray *arr1 = [NSArray arrayWithObjects:@"One", @"TWO", obj1,@"three",nil];
for (NSString *str in arr1) {
if (str != [NSNull null]){
NSLog(@"array object: %@", str);
}
}//result:One、Two、three
/* 1 nil nil:指向oc中对象的空指针 Nil:指向oc中类的空指针 NULL:指向其他类型的空指针,如一个c类型的内存指针 NSNull:在集合对象中,表示空值的对象 //非自动管理内存 若obj为nil: [obj message]将返回NO,而不是NSException 若obj为NSNull: [obj message]将抛出异常NSException</span></strong><span style="color:#454545;"> */ UILabel*label=[[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 20)]; label.backgroundColor=[UIColor greenColor]; label.textAlignment=NSTextAlignmentCenter; label.textColor=[UIColor whiteColor]; label.font=[UIFont systemFontOfSize:14]; NSString*str;//只声明不赋值也是label上的文字也不显示 NSString*str1=@""; //str==@"" 打印室空字符 //[str substringFromIndex:2]; //越界报错 // [str1 substringFromIndex:3]; // 越界报错 // str=nil; / //当str=nil 打印出 str====(null) 但lable上的文字不显示 NSLog(@"str====%@",str);//str===(null) NSLog(@"str1====%@",str1);//str1===(null) label.text=str; [self.view addSubview:label]; Person*tom=[[Person alloc]init]; tom=nil; [tom setName:@"tom"];//方法根本不会执行 NSString*name=[tom setName:@"tom"];//不会执行的方法返回就是一个nil NSLog(@"name==%@",tom); /** nil和NULL从字面意思来理解比较简单,nil是一个对象,而NULL是一个值,我的理解为nil是将对象设置为空,而NULL是将基本类型设置为空的。而且我们对于nil调用方法,不会产生crash或者抛出异常。 */ NSURL *url = nil; Class class = Nil; int *pointerInt = NULL; //在使用*pointerInt会发生错误 但是使用pointerInt打印会等于0 会爆出类型不匹配 //nil是一个对象指针为空,Nil是一个类指针为空,NULL是基本数据类型为空。 ; NSLog(@"url===%@,class==%@,pointInt==%d",url,class,pointerInt); /** // 这五个概念很容易混淆,在一些场合下他们具有同样的用法。首先解释一下“空指针”意思,空指针是指该指针未指向一块有意义的内存区。如int *p; int *p = NULL */ NSObject *obj1 = [[NSObject alloc] init]; NSObject *obj2 = [NSNull null]; NSObject *obj3 = [NSObject new]; NSObject *obj4; //obj==nil NSLog(@"obj1==%@",obj1);//obj1==<NSObject: 0x7b040850> 有地址 NSLog(@"obj2==%@",obj2);//obj2==<null>占位符 NSLog(@"obj3==%@",obj3);// obj3==<NSObject: 0x7b03c1e0> 地址 NSLog(@"obj4==%@",obj4);// nil obj4==(null) NSArray *arr1 = [NSArray arrayWithObjects:obj1, obj2, obj3, obj4, nil]; NSLog(@"arr1 count: %d", [arr1 count]);
3 因为obj4=nil,在加入obj4时就结束添加对象 NSArray *arr2 = [NSArray arrayWithObjects:obj1, obj4, obj3, obj2, nil]; NSLog(@"arr2 count: %d", [arr2 count]); //count: 1 因为obj4=nil,在加入obj4时就结束添加对象 // [NSNull null]通常作为占位符作用,如下: NSObject *obj12 = [NSNull null]; NSArray *array = [NSArray arrayWithObjects:@"One", @"TWO", obj12,@"three",nil]; for (NSString *str in array) { NSLog(@"array object: %@", str); } //result:One、Two、<null>、three NSObject *o1 = [NSNull null]; NSArray *ar1 = [NSArray arrayWithObjects:@"One", @"TWO", o1,@"three",nil]; for (NSString *str in ar1) { if (str != [NSNull null]){ NSLog(@"array object: %@", str); } }//result:One、Two、three int b; b=(int)nil; //nil被int 强转 为0 NSLog(@"b=%d",b); //(a==0) People*p=[[People alloc]init]; p=nil; p.name=@"las";//对象被置为nil, 对象的name方法将不被调用 NSMutableArray*mArray=[[NSMutableArray alloc]initWithObjects:@"1",@"2", nil]; mArray=nil; mArray.count;//数组被置为nil,下面方法不被调用,即使有越界访问或者插入操作,程序不会崩溃 [mArray insertObject:@"1" atIndex:0]; [mArray removeObjectAtIndex:3]; id test=[p print];//0x0 返回 0x0 空地址 NSString* testStr=[p print];//对象被置为nil [p print方法不被执行],返回值为nil
3.nil 和release
nil和release的作用:
nil就是把一个对象的指针置为空,只是切断了指针与内存中对象的联系;而release才是真正通知内存释放这个对象,但是在IOS中其实也不会立马释放内存,而是将内存计数器剪去1,直到计数器变为0,才会释放掉内存,所以release的目的是为了释放内存,而self.object = nil,是清空指针。
所以nil并没有释放内存,只有release才回真正释放内存。
二者使用的先后顺序:
如果没有release就直接nil,那么虽然不会出错,却等于自己制造内存泄漏了,因为nil之后release就已经不起作用了。
相反,如果在使用接口对象时只仅仅release没有设置self.myOutlet = nil,那么程序可能也不会报错,但却会十分不稳定、不健壮,很容易发生崩溃现象。
因为一个接口对象在release之后,给它所分配等内存就已经被释放了,如果释放之后系统再用到这个对象,那么程序就会crash。
如果释放之后把它的指针置为空,则即便后面的程序用到该对象,也不会崩溃。