深入探究nil和野指针

nil是一个指针对象为空,指针对象存储的是地址。

下面黑乎乎带代码是拷贝过来别人的 易于理解。并且还可作为一个反例,解释下给野指针发送消息是否崩溃的情况。

  1.nil
  >Defines the id of a null instance.
  定义一个实例为空, 指向oc中对象的空指针.
  >示例代码:
   NSString *someString = nil;
   NSURL *someURL = nil;
   id someObject = nil;
   if (anotherObject == nil) // do something

  >当对某个对象release 的同时最好把他们赋值为nil,这样可以确保安全性,如果不赋值nil,可能导致程序崩溃.
      NSArray * array = [NSArray arrayWithObjects:@"test",@"test1" ,nil];
      [array release];
      
      if (array)
      {
      //仅仅对数组release,并没有赋值为nil,在程序某个地方如果继续对数组操作,程序直接崩溃
          NSString * string = [array objectAtIndex:0];
          NSLog(@"%@",string);
      }

在这里解释为什么程序会直接崩溃呢,最准确的说应该是有时候会挂掉,因为你只是release,标记这个内存被释放,内存地址可以让其他对象所占用但是之前和array的关系并没有删除掉,如果再次使用这个对象例如在这里使用objectAtIndex,会分几种情况,不同情况结果也不一样。第一种:当再次 objectAtIndex的时候,有可能这块装test,test的内存的内容仍然存在,还没有被其他对象所占用,这个时候是不会挂掉的,依然可行。第二种:当使用当这块装test,test的内存的已经被其他对象侵占一半,但是刚好存储test,test这块没有被占用,这个时候依然不会挂掉。第三种:当这块内存被侵占的对象依然是数据,并且数据内部存在数据,这个时候调用objectAtIndex依然可行,不会挂掉,支部会取出来的数据与期望值不对,因为你这个取的对象是占用过来的新对象。第四种情况:当这块内存已经完全被其他对象多占用,并且还不是数据,你调用objectAtIndex必然会挂掉。所以上面转载复制过来的写这段话是不严谨的。

如下图例:


经验证是可以取值的,控制台打印出来test,不是在取值的时候挂掉的EXC_BAD_ACCESS野指针,你给一个被释放掉的野指针发送消息,特定情况会挂掉。

这个if(array)判断的其实是array指针是否为nil,array = release并不会置array的指针为nil,所以仍为YES,进入判断。所以在MRC中,我们在dealloc中将对象置nil。但是这样又引申出来一个知识点,为什么都是self. str = nil,这样一种方式将对象置为nil而不是_str = nil呢?这是因为_str = nil只是将对象的指针置为了nil,但是他指向的内存值仍然存在,没有被释放,浪费内存。如果用self. str = nil,会在set方法中先将新值nil做一次retain操作,没有意义,然后将旧值_str做了一次release操作,这样str指向的内存会标志为可用状态,释放。最后再将nil赋值给_str,这样做可以释放内存,又可以让对象的指针置为nil。再操作这个对象也会很保险。

在这里引用一下其他博客中的一句话在Objective-C中向nil发送消息是完全有效的——只是在运行时不会有任何作用。可以完美的确定给nil对象发送消息不会挂掉。至于原因有待考究。

在最后我们再研究一下在控制器中给一个属性

@interface PackageTourProductDetailViewController ()

@property (nonatomic,strong)NSMueableArray *arr;

@end

然后再代码里写get方法懒加载。

if(!arr){

_arr = [NSMutableArray alloc]]init];

}

这种做法判断的其实就是上面所说的情况,而不是之前简单理解的是判断这个对象是否创建了,因为你不懒加载只是@property这个属性确实存在并且也占据了内存,只是这个对象指针为nil,然后我们去判断指针为空的情况下,说明这个指针没有指向一块有用的内存,所以要创建alloc一个。这样alloc init知识创建了一个空的对象,里面有0个object,但是这个对象arr已经实实在在存在,有内存空间,只不过是一个空数组,没有长度。 

给释放掉的对象发送消息 挂掉例子。可以打印出来 但是之后随即挂掉。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值