nil和NULL的区别 以及 输出参数 堆和栈

nil和NULL

很多人都搞不清楚nil和NULL的区别,在这里对他们两个做一个说明

先看一下系统中对于他们两个的定义:


nil和NULL的区别 以及 输出参数 堆和栈_第1张图片
nilAndNULL.png

可以看到,他们两个的本质是一样的 都是__DARWIN_NULL
所以他们两个是一样的,只不过在平时用的时候语意不同,一般而言,nil表示空对象,NULL表示空地址

关于 NSNull

我们在给一个字典赋值的时候,如果赋空值如

        [dict setObject:nil forKey:@"kye1"];
        [dict setObject:NULL forKey:@"key2"];

这时候程序会崩溃,应为我们字典的value必须为对象,但是我们如果确实想给一个key赋空值的化,就要用到NSNull了

 [dict setObject:[NSNull null] forKey:@"key3"];

这样是可以赋值的:[NSNull null] 可以存储空值,是一个对象

关于 地址参数(输出参数)

在iOS中,我们经常会看到一些系统的方法,要求传入的参数为一个地址,比如我们如果写一个同步请求:

NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
    NSURLResponse * response = nil;
  
//    [NSURLConnection sendSynchronousRequest:<#(nonnull NSURLRequest *)#> returningResponse:<#(NSURLResponse *__autoreleasing  _Nullable * _Nullable)#> error:<#(NSError * _Nullable __autoreleasing * _Nullable)#>]
    
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];

这个方法中,第二个参数传入的就是NSURLResponse对象的地址,作用是请求结果会放到这个response中,而请求完之后,请求的参数会放在response中,我们就可以直接打印这个response了。
我们在平时编程的时候,也可以使用这种思想:传入参数的地址,方法中堆这个参数直接做操作,不需要返回值
比如:

我要对一个字符串拼接,方法如下:

-(void) appandStr:(NSString **)str {
//    str 为字符串,是一个对象,应为传过来的是一个地址&str 所以要使用 (NSString **)str 来找到对应栈中的地址
    *str = [*str stringByAppendingString:@"111"];
// *str :取str地址中的内容
}

调用如此下:

    //字符串拼接
    NSString * str = @"abc";
    [self appandStr:&str];
// &str 取的是str在堆中的地址
//    对象str 的本质就是一个地址
    NSLog(@"%@",str);

求数组中的最大值最小值,放啊如下:

- (void)getMaxAndMin:(NSArray *)array max:(int *)max min:(int *)min {
    //int类型应为在栈中,所以 (int *)max 表示 max在栈中的地址
    *max = [array[0] intValue];
//*max :去max地址中的内容
    *min = [array[0] intValue];
    
    for (NSNumber * num in array) {
        if (*max < num.intValue) {
            *max = num.intValue;
        }
        
        if (*min > num.intValue) {
            *min = num.intValue;
        }
    }
}

调用如下:

 int max;
    int min;
    [self getMaxAndMin:@[@(23),@(543),@(45),@(677)] max:&max min:&min];
    NSLog(@"最大值 :%d 最小值: %d",max,min);

关于堆和栈

上面的两个例子中使用的临时变量,一个是int类型的数字,一个是NSString类型的字符串,都是临时变量,但是在函数调用的时候,一个传“(int *)” 一个传“(NSString **)” 去地址的时候的操作是不同的,原因是什么呢?
这就涉及到堆和栈的知识了
同样是临时变量,都在栈上,但是int类型的数据是在栈上的,而字符串str虽然在栈上,但是栈上存放的是一个地址,地址指向的是他在堆上开辟的空间的地址,可以按下面的图来理解:


nil和NULL的区别 以及 输出参数 堆和栈_第2张图片
临时变量的内存区域

你可能感兴趣的:(nil和NULL的区别 以及 输出参数 堆和栈)