self = [super init]
Objective-C的推荐init方法写法如下:
- (id) init
{
if(self = [super init])
{
//为子类增加属性进行初始化
}
return self;
}
返回值为id类型,id类型可以赋值给其他类型指针,其他类型指针也可以赋值给id类型
obc中子类指针不能直接赋值给父类指针
[super init]也是返回self,再不改变self所指向对象的情况下,这个self跟子类的self是一样的,因为转化为消息调用时传入的Receiver都一样
如果在父类中改变了self所指向的对象,可能出现意想不到的bug:
- (id) init
{
id tmp = self;
self = [AObj alloc];
[tmp release];
//other staffs
return self;
}
BObj的init方法如下:
- (id) init
{
if(self = [super init])
{
//other staffs
}
return self;
}
这时编译能通过,但当BObj的实例使用到BObj扩充的属性时,就会出现一个运行时错误。错误的原因在于AObj的init方法用[AObj alloc]重新获得了一块仅仅适合存放AObj实例的空间。而BObj的init方法以为这是块适合存放BObj的空间。当试图读写BObj的扩充属性时便会产生运行时错误。
因此,当init方法需要重新alloc一块空间时,正确的写法如下:
- (id) init
{
id tmp = self; self = [[self class] alloc]; [tmp release];
//other staffs
return self;
}
注意第5行,[self class]将获得self指向的实例对应的类实例,本例中便是BObj。这样AObj的任何子类的init方法都能保证安全了
同样,在单例模式下,父类返回自己的对象(或把自己alloc出来的对象赋给self再返回),也会出现类似的bug,所以单例最好不要派生子类
self = [super init]的更多相关文章
- [转] "self = [super init]"的解释与潜藏bug
Objective-C的推荐init方法写法如下: - (id) init { if(self = [super init]) { //为子类增加属性进行初始化 } return self; } 这里 ...
- OC self = [super init] , 点语法 , @property
OC self = [super init] , 点语法 , @property 构造方法为啥这么写? self = [super init]; [super init] 的结果可能有三种: 第一种: ...
- iOS self = [super init]
self = [super init] 这个问题一直不太明白,今天研究了一下,在stackoverflow找到了下面的答案: http://stackoverflow.com/questions/29 ...
- [super init]方法的调用
当重新覆盖父类的init方法时,需要调用[super init]方法确认父类中的init是返回一个实例,而不是一个空的实例. 那为什么要调用这个呢? 我得猜测是这样的:因为这是一个初始化方法,需要对对 ...
- Swift - Property ''not initialized at super.init call
Property ''not initialized at super.init call 这个错误应该挺常见的的,为什么在百度上没有找到呢,stack over flow找到了,也不能说是什么解决办 ...
- 刨根问底:对于 self = [super init] 的思考
对象初始化有两种方式:[class new] 与 [[class alloc] init] 对于后者,有分配和初始化的过程,alloc 从应用程序的虚拟地址空间上为该对象分配足够的内存,并且将新对象的 ...
- 关于self和super在oc中的疑惑与分析 (self= [super init])
这个问题貌似很初级,但很容易让人忽略,me too .直到在一次面试时被问到,稀里糊涂的回答了下.实在惭愧, 面试一定都是很注重 基础的,不管高级还是初级. 虽然基础好跟基础不好都可以写代码,网上那么 ...
- swift中的如果在构造方法中使用KVC, 调用了super.init(), 报错, 基本数据类型属性找不到
swift要求, 属性必须有初始化值, 如果不对其赋值, 可以加一个?系统会默认给其包装一个可选值(直说就是nil) 如果定义一个基本类型, 建议直接赋值, 不建议使用? 下面说下标题中的问题 有时候 ...
- self = [super init] 最终解释
答: init 中调用super的 init方法来初始化自己所包含有的父类信息 1.内存分配 内存应该在[Class alloc]的时候就已经分配了,大小和类型应该由对应的Clas ...
随机推荐
- ES6 随记(3.2)-- 正则的拓展 & 数值的拓展
上一章请见: 1. ES6 随记(1)-- let 与 const 2. ES6 随记(2)-- 解构赋值 3. ES6 随记(3.1)-- 字符串的拓展 4. 拓展 b. 正则的拓展 首先又是关于 ...
- ICMP与PING解析
1.ICMP格式 ICMP是(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议族的一个子协议,用于在IP主机.路由器之间传递控制消 ...
- GIT如何使用:大杀器!所有常用指令整理
1 pwd 显示当前目录2 mkdir 创建目录 cd 进入文件3 git init 变成Git可以管理的仓库(千万不要修改目录下的.git隐藏文件夹)4 ls -ah 可以把.git文件显示出来5 ...
- 主机不能访问虚拟机web服务的问题
虚拟机是CentOs 7 iptables -Fiptables -P INPUT ACCEPT 参考:http://blog.csdn.net/abnereel/article/details/41 ...
- Activity启动的四种方式
Activity启动方式有四种,分别是: standardsingleTopsingleTasksingleInstance 可以根据实际的需求为Activity设置对应的启动模式,从而可以避免创建大 ...
- Jar 包 及运行Jar包 - 转载
Eclipse的jar file和Runnable JAR file的区别 - 及bat运行Runnable JAR文件 1.两种jar的区别 jar file是最普通的jar包,即平时我们工程中li ...
- js:s上次预览,上传图片预览,图片上传预览
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- linux应用之wget命令详解
wget是linux最常用的下载命令, 一般的使用方法是: wget + 空格 + 要下载文件的url路径 例如: # wget linuxsense.org/xxxx/xxx.tar.gz" ...
- hdu 5265
http://acm.hdu.edu.cn/showproblem.php?pid=5256 题目不错,题面忍不住骂一句mmp.......后面说ai都是正整数,我以为修改后也必须是正整数,前面又说只 ...
- 常见GAN的应用
深入浅出 GAN·原理篇文字版(完整)|干货 from:http://baijiahao.baidu.com/s?id=1568663805038898&wfr=spider&for= ...