【Objective-C】-空指针和野指针

一、什么是空指针和野指针

1.空指针

1> 没有存储任何内存地址的指针就称为空指针(NULL指针)

2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0。

下面两个都是空指针:

  1. 1 Student *s1 = NULL;
  2. 3 Student *s2 = nil; 
复制代码


2.野指针

"野指针"不是NULL指针,是指向"垃圾"内存(不可用内存)的指针。野指针是非常危险的。

二、野指针和空指针例子

接下来用一个简单的例子对比一下野指针和空指针的区别

1.首先,打开Xcode的内存管理调试开关,它能帮助检测垃圾内存

<ignore_js_op>21234543-0a0055d60baa421e88b297bf7af34dc0.png <ignore_js_op>21234552-44874b01924b4f0bb063d96ea360e1ee.png 

21234601-235c040211724007929ab0c968f96772.png 


2.自定义Student类,在main函数中添加下列代码

  1. 1 Student *stu = [[Student alloc] init];
  2. 3 [stu setAge:10];
  3. 5 [stu release];
  4. 7 [stu setAge:10];
复制代码



运行程序,你会发现第7行报错了,是个野指针错误!
21234838-a6822222eb4f4fd9bc8ea5a3a653d676.png 

3.接下来分析一下报错原因

1> 执行完第1行代码后,内存中有个指针变量stu,指向了Student对象

Student *stu = [[Student alloc] init];
21235352-9537ce2d67e34abb9d84bb642ac4266e.png 
假设Student对象的地址为0xff43,指针变量stu的地址为0xee45,stu中存储的是Student对象的地址0xff43。即指针变量stu指向了这个Student对象。

2> 接下来是第3行代码

[stu setAge:10];

这行代码的意思是:给stu所指向的Student对象发送一条setAge:消息,即调用这个Student对象的setAge:方法。目前来说,这个Student对象仍存在于内存中,所以这句代码没有任何问题。

3> 接下来是第5行代码

[stu release];

这行代码的意思是:给stu指向的Student对象发送一条release消息。在这里,Student对象接收到release消息后,会马上被销毁,所占用的内存会被回收。

(release的具体用法会放到OC内存管理中详细讨论)
22000254-459d4d90f04640f0b5f833a6a0cae32c.png 
Student对象被销毁了,地址为0xff43的内存就变成了"垃圾内存",然而,指针变量stu仍然指向这一块内存,这时候,stu就称为了野指针!

4> 最后执行了第7行代码

[stu setAge:10];

这句代码的意思仍然是: 给stu所指向的Student对象发送一条setAge:消息但是在执行完第5行代码后,Student对象已经被销毁了,它所占用的内存已经是垃圾内存,如果你还去访问这一块内存,那就会报野指针错误。这块内存已经不可用了,也不属于你了,你还去访问它,肯定是不合法的。所以,这行代码报错了!

4.如果改动一下代码,就不会报错

  1. 1 Student *stu = [[Student alloc] init];
  2. 3 [stu setAge:10];
  3. 5 [stu release];
  4. 7 stu = nil;
  5. 9 [stu setAge:10];
复制代码


注意第7行代码,stu变成了空指针,stu就不再指向任何内存了
22001111-c5456937e13b4074850416deff2060ec.png 
因为stu是个空指针,没有指向任何对象,因此第9行的setAge:消息是发不出去的,不会造成任何影响。当然,肯定也不会报错。

5.总结

1> 利用野指针发消息是很危险的,会报错。也就是说,如果一个对象已经被回收了,就不要再去操作它,不要再尝试给它发消息

2> 利用空指针发消息是没有任何问题的,也就是说下面的代码是没有错误的:

[nil setAge:10]; 

原文链接:http://www.cnblogs.com/mjios/archive/2013/04/22/3034788.html

posted @   itlover2013  阅读(241)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示