[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
如有错误,欢迎随时指正!
[BS-21] 关于OC中对象与指针的思考的更多相关文章
- OC中对象拷贝概念
OC中的对象拷贝概念,这个对于面向对象语言中都会有这种的问题,只是不同的语言有不同的解决方式:C++中有拷贝构造函数,Java中需要实现Cloneable接口,在clone方法中进行操作.但是不过OC ...
- OC中的野指针(僵尸指针)
涉及到内存管理问题的都是类类型的变量,而在OC中我们操纵这些对象都是通过操纵指向他们的指针来完成的,一致很多时候会忽略指针存在.比如定义UIView * view = [[UIView alloc]i ...
- OC中对象元素的引用计数 自动释放池的相关概念
OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念 一.数组对象是如何处理对象元素的引用计数问题[objc] view plaincopy 1. // 2. / ...
- OC中的野指针,空指针,nil,Nil,NULL,NSNULL小结
周末与一个老朋友吃饭聊天,因为他正在培训班学习iOS开发,就随便聊了几句,发现自己OC基础上的欠缺和一些知识点的混淆.特此整理如下. 1.空指针 没有存储任何内存地址的指针就称为空指针(NULL指针) ...
- OC中的self指针
在OC中,self是一个指针,方法和属性可以通过self.function进行访问:成员变量使用self->变量名进行访问.调用方法还可以用[self function]; OC中的self有点 ...
- 编译时和运行时、OC中对象的动态编译机制
编译时 编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如Java只有JVM识别的字 ...
- oc中对象的初始化
在.m文件中使用对象方法: - (id)init { _name =@"zhangsan"; _age = 18; return self; } 然后通过main方法中进行创建对象 ...
- OC中对象的description方法
周所周知,我们在做项目时, 可以在类的.m文件中重写该类的对象的描述description方法: 示例: -(NSString *)description{ NSString *str = [N ...
- OC中nil、Nil、NULL、NSNull的区别
nil:指向OC中对象的空指针 e.g.: NSString *string = nil; Nil:指向OC中类的空指针 e.g.:Class class = Nil; NULL:指向其他类型的 ...
随机推荐
- http页面转发和重定向的区别
一.调用方式 我们知道,在servlet中调用转发.重定向的语句如下:request.getRequestDispatcher("new.jsp").forward(request ...
- Java发展史之Java由来
Java:由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称.Java语言是一种可以撰写跨平台应用软件的面向对象的程序设计语言,由当时任职太阳微系统的 ...
- AC之路开始了~
已经进行了半年ACM的学习啦~虽然实力很弱但是仍然快快乐乐的慢慢学习... 新建了我的博客~ 记录A题经验 感悟学习点滴~ 加油~
- PHP 错误与异常 笔记与总结(1)错误(Deprecated,Notice,Warning)
[常见的错误类型] ① 语法错误 [例1]程序语句结尾少了';' <?php $username = "dee" //少了分号; echo $username; 输出: ( ...
- 如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;)。
1.如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;). 2.select查询的多个字段之间要用逗号“,”分割,如果查询涉及多个表,那多个表之 ...
- 使用FROM确认按钮(键盘13号键)提交特性并使用ajax.POST提交.
如果又想使用FROM确认按钮(键盘13号键)提交特性 还能继续用AJAX.POST提交.就需要使用return false 来阻止FROM默认提交 代码如下: HTML页面 这里最关键就是用了ret ...
- 基于LR的数据库性能测试
web services协议 在LR的web services协议中提供了如下函数进行数据库的连接和执行sql语句,以实现对数据库的性能测试,也可以实现向数据库中自动生成批量数据. lr_db_dis ...
- UBUNTU 14.04 安装 OPENCV 2.4.9
1. 从OpenCV.org 下载源代码 opencv-2.4.9.zip 2. 解压到准备好的目录 unzip opencv-2.4.9.zip 3. 进入源码目录,创建release目录 cd ...
- URL编码数据转换为JSON数据
NSString *urlString; urlString=[self URLDecodedString:urlString]; -(NSString *)URLDecodedString:( ...
- C++ 实现 发送HTTP Get/Post请求 good
1.简述 最近简单看了一下关于HTTP请求方面的知识,之前一直用Qt来实现,有专门HTTP请求的QNetworkAccessManager类来处理,实现也比较简单,这里主要讲解一下用C++代码来实现H ...