oc——nil Nil NULL NSNull

本文深入探讨Objective-C中的nil、Nil及NULL的区别与联系,并解析空对象的使用特性,同时介绍了NSNull类的应用场景及其在容器中的特殊意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

nil&Nil&NULL

- (void)nil_Nil_NULL
{
    NSLog(@"nil = %p, Nil = %p, Null = %p", nil, Nil, NULL);
    NSLog(@"equal(nil, Nil) = %d, equal(nil, NULL) = %d, equal(Nil, NULL) = %d", nil == Nil, nil == NULL, Nil == NULL);
    
    int *pi;
    pi = nil;
    pi = Nil;
    pi = NULL;
    
    NSObject *obj;
    obj = nil;
    obj = Nil;
    obj = NULL;
    
    Class cls;
    cls = nil;
    cls = Nil;
    cls = NULL;
}
output:
nil = 0x0, Nil = 0x0, Null = 0x0
equal(nil, Nil) = 1, equal(nil, NULL) = 1, equal(Nil, NULL) = 1
总结:
  • nil,Nil,NULL都是指针类型常量0,表示指针为空,不指向任何对象,可交互使用,语法上无问题
  • nil,Nil,NULL语义上不同,可理解为nil为(id)0,Nil为(Class)0,NULL为(void *)0
  • 为增强代码可读性,instance object指针使用nil,class object指针使用Nil,c类型指针使用NULL

空对象

@interface FBAnimal : NSObject
{
@public
    int _food;
}

@end

@implementation FBAnimal

- (void)info
{
    NSLog(@"food = %d", _food);
}

@end
- (void)empty_obj
{
    NSLog(@"instance object not nil");
    FBAnimal *animal1 = [[FBAnimal alloc] init];
    animal1->_food = 5;
    [animal1 info];
    
    NSLog(@"instance object nil");
    FBAnimal *animal2 = nil;
    //animal2->_food = 8;
    [animal2 info];
    
    NSLog(@"class object not Nil");
    Class cls1 = [FBAnimal class];
    FBAnimal *animal3 = [[cls1 alloc] init];
    animal3->_food = 15;
    [animal3 info];
    
    NSLog(@"class object Nil");
    Class cls2 = Nil;
    FBAnimal *animal4 = [[cls2 alloc] init];
    //animal4->_food = 18;
    [animal4 info];
}
output:
instance object not nil
food = 5
instance object nil
class object not Nil
food = 15
class object Nil
总结:
  • 调用方法成员本质是转换为objc_msgSend系列函数,而objc_msgSend系列函数内置了空对象判断机制,因此空对象调用方法成员不会crash,因此可omit对象为空判断,节省代码,提高执行效率
  • 访问数据成员本质是通过offset直接访问内存空间,没有任何判断对象为空机制,因此空对象访问数据成员必然crash
注:c++中实例对象不管是调用方法成员或访问数据成员都没有任何判断对象为空机制,因此空对象不管调用方法成员或访问数据成员都必然crash

NSNull

NSNull是类,单例实现,空对象(非nil或Nil),常用在容器中表示容器元素为空,容器元素不允许空对象(nil或Nil),空对象(nil或Nil)在容器中作为容器结束标记符,起哨兵作用
- (void)use_NSNull
{
    NSString *animal = nil;
    
    NSArray *animals1 = [NSArray arrayWithObjects:@"dog", [NSNull null], @"cat", nil];
    NSArray *animals2 = [NSArray arrayWithObjects:@"dog", nil, @"cat", animal, nil];
    NSArray *animals3 = [NSArray arrayWithObjects:@"dog", animal, @"cat", nil];
    
    NSLog(@"animals1 count = %ld", animals1.count);
    NSLog(@"animals2 count = %ld", animals2.count);
    NSLog(@"animals3 count = %ld", animals3.count);
}
output:
animals1 count = 3
animals2 count = 1
animals3 count = 1
注:容器添加元素时,运行时判断,一旦遇到空对象(nil或Nil),容器添加元素结束,ignore之后元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值