关于 self = [super init];

[plain] view plaincopyprint?

  1. - (id)init {
  2. self = [super init]; // Call a designated initializer here.
  3. if (self != nil) {
  4. // 省略其他细节
  5. }
  6. return self;
  7. }

容易让人困惑的地方在于,将父类初始化之后,将其返回的对象指针覆盖当前对象的指针。

这种方式令人费解,目前暂时找不到官方解释这么做的原因。

官方文档 有解释。

我们先分以下几种情况分别分析:(假设superSelf是[super init]的返回值)

1 superSelf == nil

此时父类初始化失败,self随之被赋值为nil并返回,表现正常。

2 superSelf == self

大部分类的初始化都是这个结果。此时赋值没有任何影响。

3 superSelf != self

这种情况正是大部分人疑惑的地方。执行self = [super init]之后,

我们创建的对象将会被重定向到另外一块内存上。接下来重点解释这种情况。

首先,出现父类指针跟子类指针不一样的情况其实就是父类的init方法返回的对象跟原先创建的对象不一样,分为以下几种:

1 单件。

此时如果执行self = [super init]将使所有子类指向这个单件的内存。

这不仅使所有子类互相修改数据,甚至访问子类自己增加的变量的时候,可能会崩溃。

建议不要继承单件、或者保证单件的子类也是单件。

2 ClassClusters(类簇),初始化方法返回了不同的子类。

以下是对象初始化后,返回不同的子类的例子:

[plain] view plaincopyprint?

  1. NSString *str1 = [NSString alloc];
  2. NSString *str2 = [str1 initWithString:@"hello"];

上面的str1和str2是不一样的对象,存在于不同的内存块中,在GNUStep里面,str1是GSPlaceholderString对象,str2是GSCInlineString对象。

3 共享。

先看例子:

[plain] view plaincopyprint?

  1. NSNumber *n1 = [[NSNumber alloc] initWithInt:1];
  2. NSNumber *n2 = [[NSNumber alloc] initWithInt:1];

以上的n1和n2,指向了同一块内存!

由于NSNumber是创建之后就不能修改的对象,所以Foundation在这里做了一些优化,相同数值的NSNumber对象将共享同一块内存。

4 父类可能在初始化中释放了当前的对象并创建了新的内存区域。

这时,子类需要将self指向新的内存区域才能正常工作。所以一定要执行self = [super init];

总结:

在初始化方法中使用self = [super init]语句是Objective-C的标准做法。

一般情况下都要用以上语句来防止父类改变对象的内存地址导致self指针指向无效内存。

在父类是单件、类簇或者有共享资源的时候,必须依照实际情况考虑是否加上这行代码。

总之,当需要继承父类的时候,调用父类的init之前,必须知道父类的init方法的工作方式。

关于 self = [super init];,布布扣,bubuko.com

时间: 2024-08-07 16:58:35

关于 self = [super init];的相关文章

Objective-C语言的 if ( self = [super init] )22

我们先假设现在自己创建了个类,我们起名叫MyObject,继承于NSObject. 继承知道吧,就是你这个子类(MyObject)如果什么都不写的话,和父类(NSObject)就是一模一样的. OC里几乎所有的类的根源都是NSObject,都是在NSObject的基础上增加成员变量.函数. 父类不是你自己写的类,你不敢保证它是安全的,能否成功初始化,你有可能不知道里面是什么样子的. self = [super init],你可能对这步做法可能难以理解.self指向了父类初始化的内存地址.类的初始

init()方法必须使用super.init(config)的原因--Servlet

原 因: 一个servlet在它的init()方法中传递它的ServletConfig实例,在其他的方法中却不可以.当一个servlet在 init()方法外需要调用config对象时就会产生问题.使用super.init(config)语句就解决了这个问题,该语句通过唤醒 GenericServlet的init()方法, 该方法保存了这个config对象的一个引用,以备将来使用.那么,一个servlet是怎样利用这个保存的引用的呢?是通过自身唤醒方法.在执行 中,GenericServlet类

关于 objective - C 的 super init

[super init] 的结果可能有三种: 第一种: [super init] 初始化成功,这个是最最正常的情况. 第二种: [super init] 初始化失败,我们都知道oc的两步创建,alloc开辟内存空间,init初始化对象,但是init还有另外一个作用,在初始化失败的时候,init方法会返回一个nil.回头行文的最上面,如果self为nil,那么if(self)语句的内容,将不被执行,已确保程序健壮安全. - (instancetype)init { self = [super in

Objective-C语言的 if ( self = [super init] )

我们先假设现在自己创建了个类,我们起名叫MyObject,继承于NSObject. 继承知道吧,就是你这个子类(MyObject)如果什么都不写的话,和父类(NSObject)就是一模一样的. OC里几乎所有的类的根源都是NSObject,都是在NSObject的基础上增加成员变量.函数. 父类不是你自己写的类,你不敢保证它是安全的,能否成功初始化,你有可能不知道里面是什么样子的. self = [super init],你可能对这步做法可能难以理解.self指向了父类初始化的内存地址.类的初始

[Obj-C笔记] "self = [super init]"的解释与潜藏bug

转自:http://blog.csdn.net/aoyuehan11/article/details/10268231 Objective-C的推荐init方法写法如下: - (id) init { if(self = [super init]) { //为子类增加属性进行初始化 } return self; } 这里涉及了几个问题, 1. [super init]的作用: 面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化. 2. self 为什么要赋值为[super in

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 = [super init]"的解释与潜藏bug

Objective-C的推荐init方法写法如下: - (id) init { if(self = [super init]) { //为子类增加属性进行初始化 } return self; } 这里涉及了几个问题, 1. [super init]的作用: 面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化. 2. self 为什么要赋值为[super init]: 简单来说是为了防止父类的初始化方法release掉了self指向的空间并重新alloc了一块空间.这时的话,[

刨根问底:对于 self = [super init] 的思考

对象初始化有两种方式:[class new] 与 [[class alloc] init] 对于后者,有分配和初始化的过程,alloc 从应用程序的虚拟地址空间上为该对象分配足够的内存,并且将新对象的引用计数加1.将对象的成员变量初始为零,init 会做真正的初使化工作,为对象的实例变量赋予合理有用的值. 一般不推荐使用[class new],而推荐使用[[class alloc] new],查看源码分析一下: + new { id newObject = (*_alloc)((Class)se

iOS self = [super init]

self = [super init] 这个问题一直不太明白,今天研究了一下,在stackoverflow找到了下面的答案: http://stackoverflow.com/questions/2956943/why-should-i-call-self-super-init 我对这些答案简单翻译总结下: 要明白这个问题,首先要知道self 是什么东西,我们什么时候会用到self.