Objective-C中的alloc和init问题
从开始学的NSString *name=[[NSString alloc] init] 起,仅仅这句话是分配内存空间,一直在用,从来没考虑过它的内部是怎么实现的。今天无意中看到了这一句代码:
NSString *name = [NSString alloc];
NSLog(@"%p",name);
name = [name init];
NSLog(@"%p",name);
试着打印了一下,发现两个的内存地址不一样:
alloc是开辟一个内存空间,init是初始化,为什么初始化不在原有的内存空间上初始化,而是重新开辟一个内存空间。于是开始查资料,这时又发现了一个新的迷惑:
NSObject *obj = [NSObject alloc];
NSLog(@"%p",obj);
obj = [obj init];
NSLog(@"%p",obj);
打印结果:
怎么地址又变一样了?再打印NSArray的试一试:
NSArray *person = [NSArray alloc];
NSLog(@"%p",person);
person = [person init];
NSLog(@"%p",person);
再次打印结果:
仍然是不一样的。原因是什么呢?首先看看NSStrng的init方法吧:
-(id)init{
if(self = [super init]) {// 重新赋值
//…
}
}
从代码中可以分析,self=[super init]如果不为nil,就重新分配内存空间,这就解释了为什么 NSString,NSArray的调用alloc]init]方法后,内存地址会不一样,但是NSObject为什么会一样呢,我们知道NSObject是一切类的基类,当[[NSString alloc]init]执行时,调用的[super init]就是 NSObject中的init方法,既然NSObject身为基类,它也就无法调用super init,所以当NSObject执行[[NSObject alloc]init]时,也就没有了init重新分配空间这一环节。
至于苹果公司为什么初始化一个实例要分两步,个人认为是方便构造后初始化不同的方法,如果用 new关键字,只能调用一个init,而不能调用initWithName等方法。
知识拓展:
NSString alloc之后,没有init,那么这部分alloc后的内存空间可不可以用?答案是显而易见的,如果可以用,苹果公司也就没必要提供一个init方法,那么alloc后的指针称为什么呢? 悬挂指针。
如果一个地方指针既不为空,也没有被设置为指向一个已知的对象,则这样的指针称为悬挂指针。在程序里面是很危险的事。当程序运行使用该指针时,程序不能判断指针的合法性,将会产生很严重的错误。
【扫描关注更多精彩内容】
微信公众号:xiaoniu
Objective-C中的alloc和init问题的更多相关文章
- Object c中的alloc和init问题
从开始学的NSString *name=[[NSString alloc] init] 起,老师教这句话是分配内存空间,一直在用,从来没考虑过它的内部是怎么实现的.今天无意中看到了这一句代码 NSSt ...
- iOS中alloc与init
面向对象的3大特性,封装继承和多态. 我遇到过封装相关的问题,因为初级封装简单,常常暴露出被你封装的接口,进一步进行高级封装隐藏接口的时候才发现,封装是一门学问,而这门学问得从最基础的alloc与in ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- alloc、init你弄懂50%了吗?
前言 这是一篇我记录对alloc.init分析思考的笔记.如果读者想看懂我的第二个思考,可能需要您至少了解内存的分段分页管理,如果您对其一点都不知道,可以先看这篇软文简单了解一下.另外很重要的一点是, ...
- iOS 中的视图函数 init initwithnib viewDidLoad viewWillAppear的总结
我要总结的函数主要是这几个: UIView *view-如果view还没有被初始化的话,getter方法会先调用[self loadView],如果getter或者setter方法被重写了,子类中的g ...
- objective C中的字符串NSStirng常用操作
objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的 ...
- NVidia Jetson Ubuntu 18.04 安装ROS过程中运行sudo rosdep init指令出错
参考:https://www.cnblogs.com/xuhaoforwards/p/9399744.html 安装ROS过程中运行sudo rosdep init后,出现如下错误LOG: ERROR ...
- Objective C中的ARC的修饰符的使用---- 学习笔记九
#import <Foundation/Foundation.h> @interface Test : NSObject /** * 默认的就是__strong,这里只是做示范,实际使用时 ...
随机推荐
- 29Mybatis_整合ehcache以及应用场景
ehcache是一个分布式缓存框架. 分布缓存
- 下列哪个为JSP的小脚本的标签?(选择1项)
下列哪个为JSP的小脚本的标签?(选择1项) A.<% %> B.<@ %> C.<%! %> D.<%– %> 解答:A
- 【BZOJ】2555: SubString(后缀自动机)
http://www.lydsy.com/JudgeOnline/problem.php?id=2555 学到了如何快速维护right值orz (不过这仍然是暴力维护,可以卡到O(n) 首先我们在加一 ...
- wifi的web 认证。
wifi的web 认证.wifidog+authpuppy+php 或者Wiwiz Auth API
- python3----requests
import requests def get_html_text(url): try: r = requests.get(url, timeout=30) r.raise_for_status() ...
- tcp断开时分几步
连接时是三次握手 断开时是四次握手,因为它是半关闭造成的
- 安装顺序----------SQL server 2008 r2;VS2008;VS2010;
[1]一般先安装了VS2008 再安装SQL server 2008 r2会报错:安装sql server 2008 报错“检查 Microsoft Visual Studio 2008 的早期版本” ...
- $(document).scrollTop()与$(window).scrollTop()
$(document).scrollTop() 获取垂直滚动的距离 即当前滚动的地方的窗口顶端到整个页面顶端的距离 要获取顶端 只需要获取到scrollTop()==0的时候 就是顶端了 要获取底端 ...
- chrome不支持字体12px
如果网页字体小于12px的话,人眼看着会不太舒服,所以chrome的最小字体为12px. 如果想要缩小字体,可以尝试用CSS3中的 transform: scale(相应的缩小倍数)来实现. 不过不推 ...
- tomcat------->简单配置
主机名:www.snowing.com 域名:snowing.com http://主机+服务器端口号/path(web应用)/xxx.html 例: http://localhost:8080/it ...