Objective-c:关于self = [super init]的问题

Posted

技术标签:

【中文标题】Objective-c:关于self = [super init]的问题【英文标题】:Objective-c: Questions about self = [super init] 【发布时间】:2013-09-09 07:04:02 【问题描述】:

我在 init 方法中看到了self = [super init]。我不明白为什么。 [super init] 不会返回超类吗?如果我们指向self = [super init],我们不会得到self = superclass吗? 这是一个示例代码片段

- (id)init 

    if (self = [super init]) 
        creationDate = [[NSDate alloc] init];
    
    return self;

希望有人可以为我澄清这一点。谢谢你。

【问题讨论】:

搜索“isa指针”。 这里解释得很好:cocoawithlove.com/2009/04/…. 【参考方案1】:

假设MyClassBaseClass 的子类,当 你打电话

MyClass *mc = [[MyClass alloc] init];
    [MyClass alloc] 分配一个 MyClass 的实例。 init 消息被发送到此实例以完成初始化过程。 在该方法中,self(这是所有 Objective-C 方法的隐藏参数)是 步骤 1 中分配的实例。 [super init] 调用init超类实现 相同(隐藏) self 参数。 (这可能是你理解错误的地方。)

    BaseClassinit 方法中,self 仍然是MyClass同一个实例。 这个超类的 init 方法现在可以

    self进行基础初始化并返回self,或者 丢弃 self 并分配/初始化并返回不同的对象。

    回到MyClassinit 方法:self = [super init] 现在是任一

    在步骤 1 中分配的 MyClass 对象,或 有些不同。 (这就是为什么人们应该检查并使用这个返回值。) 初始化完成(使用超类init返回的self)。

所以,如果我正确理解了你的问题,那么重点是

[super init]

使用self 参数调用init 的超类实现, 这是一个MyClass 对象,而不是BaseClass 对象。

【讨论】:

在第 4 步中,“不同的对象”会是 nil 以外的任何东西吗?【参考方案2】:

因为你在 if 条件中有 Question self = [super init] 暗示了一个特定的含义。

首先[super init] 给出了当前正在使用的现有类的超类的初始化。使用[super init] 给出了超类初始化,表明该类的对象存在。

现在,当您使用 self = [super init] 时,这意味着您正在将类分配给自身,以便进一步利用同一类。

最后你把它放在 if 条件中为if(self = [super init]) 这意味着你正在检查类的对象是否存在,而不是防止应用程序的错误行为。

我想现在很清楚了!!!

【讨论】:

【参考方案3】:

@MartinR 有一个很好的答案。但是你有没有想过为什么“[super init] 用相同的(隐藏的)self 参数调用 init 的超类实现。(这可能是你理解错误的一点。)”在他的第三点中有效?

这是 Big Nerd Ranch 指南第 3 版的摘录,第 2 章目标 C 阐明了这一点

“超级是如何运作的?通常当你向一个对象发送消息时, 对该名称的方法的搜索从对象的类开始。如果 没有这样的方法,在超类中继续搜索 目的。搜索将继续沿继承层次结构,直到 找到合适的方法。 (如果它到达层次结构的顶部并且 没有找到方法,抛出异常。)”

“当您向超级用户发送消息时,您正在向自己发送消息, 但是对方法的搜索跳过对象的类并从 超类。”

这段代码显示了 ios 运行时如何执行这个任务

objc_msgSendSuper(self, @selector(init));

【讨论】:

【参考方案4】:

您声明的每个方法都有两个隐藏参数:self 和 _cmd。

以下方法:

- (id)initWithString:(NSString *)aString;

由编译器转换为以下函数调用:

id initWithString(id self, SEL _cmd, NSString *aString);

查看此链接了解更多信息:

http://www.cocoawithlove.com/2009/04/what-does-it-mean-when-you-assign-super.html

【讨论】:

【参考方案5】:

Self = [超级初始化];

根据 JAVA,this 表示指向实例本身的指针,因此对象可以向自己发送消息。

Self在目标C中的含义相同,

根据JAVA,Super表示允许访问基类或父类

在目标 C 中 Super 的含义相同,

现在init实例来完成初始化过程。

【讨论】:

【参考方案6】:

我会认为它是初始化所有超级变量等,然后在返回之前初始化扩展类变量。

【讨论】:

【参考方案7】:

[super init] 等同于 [self superclass_variant_of_init]

如果要向超类发送消息,还有另一种方法(不使用运行时库):

[[self superclass] init];

【讨论】:

【参考方案8】:

来自Apple's Documentation:

因为一个 init... 方法可能返回 nil 或一个不是显式分配的对象,所以使用 alloc 或 allocWithZone: 返回的实例而不是初始化器返回的实例是危险的。考虑以下代码:

id myObject = [MyClass alloc];
[myObject init];
[myObject doSomething];

上面示例中的 init 方法可能返回 nil 或替换为不同的对象。因为您可以在不引发异常的情况下向 nil 发送消息,所以在前一种情况下不会发生任何事情,除非(可能)令人头疼的调试问题。但是您应该始终依赖于初始化的实例,而不是刚刚分配的“原始”实例。因此,您应该将分配消息嵌套在初始化消息中,并在继续之前测试从初始化器返回的对象。

id myObject = [[MyClass alloc] init];
if ( myObject ) 
    [myObject doSomething];
 else 
    // error recovery... 

【讨论】:

以上是关于Objective-c:关于self = [super init]的问题的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C:使用 self.navigationController 和自定义 UINavigationController

已知多项式A=3x²-5x+3,B=2x²-5x-1,比较两个多项式的大小。(要求答案有过程)

Objective-C self->_ivar 访问与显式与隐式 self->

objective-c 怎么实现点击一个按钮弹出新的窗口

我可以使用 [self retain] 在objective-c 中保存对象本身吗?

Objective-C语言的 if ( self = [super init] )啥意思?