zoukankan      html  css  js  c++  java
  • [BS-21] 关于OC中对象与指针的思考

    关于OC中对象与指针的思考

    1. 创建对象:

      OC中可通过代码Person *p = [[Person alloc] init];创建了一个对象p。该过程中内存情况为:

      在当前线程的栈(默认1M)中,存在一个(Person *)类型的变量p,因为C语言中前面带*的变量都是指针变量,故也可理解为栈中有一个Person数据类型的指针变量p(p是指针,p不光自己有地址,它4B大小的空间中存储着别的变量的地址)。

      同时在ios系统管理的堆中(所有app共享)通过alloc分配了一块能装下Person数据类型的存储空间(它有一个地址,假设为0x168168),通过init方法,将该存储空间中Person数据中的成员变量的值全部初始化为0。

      指针变量p是(Person *)类型,它4B的空间中存储着堆中[Person alloc]出来的那块内存空间的内存地址0x168168。 从此以后我们就会称指针变量p为一个对象,可以直接通过p来访问对象内存成员变量,调用对象内部的地址。

    2. 总结:

        在OC中,从本质上看,对象是堆内存中按照某XXClass数据类型(类) alloc出来的一块有地址的内存空间,但这块内存空间必须要有栈中的某个指针(XXClass类型)指向它,否则它的引用计数为0,就会被系统自动回收。

        所以,在OC中,从表面上看,对象就是存在于栈中的某XXClass类型的指针变量(如Person *p),但是要求该指针变量中必须保存着堆内存中的一块有地址的内存(NSNull空对象也有地址),这样的指针变量才是对象。

    举例:
    Person *p = [[Person alloc] init];   //可以说p是对象
    Person *m;  // 不能说m是对象,它只是Person数据类型的一个指针变量
    Person *n = p; //可以说n是对象,因为将p赋值给n,n和p都保存着堆中alloc出来的内存块(真正的对象)的地址0x168168,并且此时堆中的内存块的引用计数为2

     

    3. 特殊的数据类型及其变量

    在OC中常用的数据类型主要有: 基本数据类型(int/float/char/double等)、 系统框架类、 自定义类。

    除了以上几种常用的,还有一些定义在<objc/objc.h>头文件中的本身就是指针的数据类型(如id类型、Class类型、Sel类型、Method类型、Ivar类型等),这些自身就是指针的数据结构,在用它们定义指针变量(OC表面上的对象)时,是不需要加*号的。

    如 id boy = [[Person alloc] init];    Class personClass = [Person class]; //类方法来创建类对象

    //以下均定义在 <objc/objc.h>头文件中
    
    /// An opaque type that represents an Objective-C class.
    typedef struct objc_class   *Class; //带*号的Class是指针类型
    
    /// A pointer to an instance of a class.
    typedef struct objc_object   *id;   //带*号的id是指针类型
    
    /// An opaque type that represents a method selector.
    typedef struct objc_selector *SEL;    //带*号的id是指针类型
    
    /// An opaque type that represents a method in a class definition.
    typedef struct objc_method *Method;   //带*号的id是指针类型
    
    /// An opaque type that represents an instance variable.
    typedef struct objc_ivar *Ivar;    //带*号的id是指针类型
    
    /// An opaque type that represents a category.
    typedef struct objc_category *Category;   //带*号的id是指针类型
    
    /// An opaque type that represents an Objective-C declared property.
    typedef struct objc_property *objc_property_t;  //带*号的id是指针类型

     //创建类对象

        Class personClass = [Person class];

        NSLog(@"类对象:%@--%p",personClass,personClass);

        //类对象:Person--0x100ea03a8

    //id类型

        id boy = [[Man alloc]init];

      NSLog(@"id类型:%@--%p",boy,boy);

        //id类型:<Man: 0x7f8c89f230b0>--0x7f8c89f230b0

     

    4. 综上:OC中所有的对象表面上看都是存储着堆中内存块地址的 (xxx类 *)p 或者 (指针类型)p 的指针。而真正的对象是堆内存中的【xxx类 alloc】出来的内存块。 

    文章原创,转载请注明出处:http://www.cnblogs.com/stevenwuzheng/p/5501266.html

    如有错误,欢迎随时指正!

  • 相关阅读:
    发现了一个前端导航网站
    git 设置区分大小写
    分享一个 thinkphp 分页的24款样式
    thinkphp5结合layui表单和图片上传
    tp5分页+循环子字段
    tp5 + layui 分页
    composer的安装
    thinkphp 管道写法及volist标签属性
    把常见的分隔符按照自定义的格式分割
    spring mvc 框架下的maven打包发布方法
  • 原文地址:https://www.cnblogs.com/stevenwuzheng/p/5501266.html
Copyright © 2011-2022 走看看