[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

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

 

posted @ 2016-05-17 13:28  stevenwuzheng  阅读(1006)  评论(0编辑  收藏  举报