zoukankan      html  css  js  c++  java
  • 【Objective-C】09-空指针和野指针

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

    1.空指针

    1> 没有存储不论什么内存地址的指针就称为空指针(NULL指针)

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

    以下两个都是空指针:

    1 Student *s1 = NULL;
    2 
    3 Student *s2 = nil;

     

    2.野指针

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

     

    二、野指针和空指针样例

    接下来用一个简单的样例对照一下野指针和空指针的差别

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

      

     

     

    2.自己定义Student类。在main函数中加入下列代码

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

    执行程序。你会发现第7行报错了。是个野指针错误!

     

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

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

    Student *stu = [[Student alloc] init];

    如果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内存管理中具体讨论)

    Student对象被销毁了,地址为0xff43的内存就变成了"垃圾内存",然而。指针变量stu仍然指向这一块内存,这时候。stu就称为了野指针

     

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

    [stu setAge:10];

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

    所以。这行代码报错了。

     

    4.假设修改一下代码,就不会报错

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

    注意第7行代码,stu变成了空指针,stu就不再指向不论什么内存了

    由于stu是个空指针。没有指向不论什么对象,因此第9行的setAge:消息是发不出去的,不会造成不论什么影响。当然。肯定也不会报错。

     

    5.总结

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

    2> 利用空指针发消息是没有不论什么问题的,也就是说以下的代码是没有错误的:

    [nil setAge:10];
  • 相关阅读:
    SpringBoot开发中的坑 记录一些
    MongoDB 文档【行】
    MongoDB 集合【表】
    MongoDB 数据库
    MongoDB 基础
    gitlab或github下fork后如何同步源的新更新内容?
    解决:android源码同步repo sync 时出现的fatal:duplicate path错误
    android ROM刷机updater-script单刷补丁包脚本
    一键解包/打包boot.img/recovery.img工具(高通/MTK双版 支持android 5.1以上)
    解决:github上传时出现error: src refspec master does not match any
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7202493.html
Copyright © 2011-2022 走看看