【问题标题】:Understanding 'self' and setting self to super了解“自我”并将自我设置为超级
【发布时间】:2012-08-25 09:47:41
【问题描述】:

我一直在学习一些教程,但我对自己感到失望。有人可以帮忙吗?

我有下面的init,它是一个实例方法。

- (id) initWithScore:(int) s {
    self = [super init];

    if (self) {
        score = s;

    }

    return self;
}

现在阅读我将 self 设置为 super init 的代码,因此 self 现在指向 super。然后我检查 self 是否有效并设置分数等于我在 InitWIthScore 上发送的值。到目前为止,我已经得到了这个。

但是现在我返回指向超类的self,那么我如何返回我的子类呢?

因此,假设有人调用我的类传入 100,我的代码返回的是 super 而不是类,那么它是如何工作的?调用代码的 score 值是如何为 100 的?

当然,是的,它确实有效,但我不知道为什么:-(

【问题讨论】:

    标签: objective-c ios


    【解决方案1】:

    此构造允许初始化程序(super 初始化程序和您正在编写的初始化程序)以一种失败的方式 - 如果对象无法初始化,则返回 nil。这也是为什么您在调用super 后在init 中检查nil

    selfsuper 都指向内存中的相同数据结构,即您分配的对象。区别在于这些特殊指针的语言语义:

    当使用self 时,Objective-C 编译器将以您当前的类型启动方法和重载解析。

    当使用super 时,Objective-C 编译器将在您的类的直接超类型处启动方法和重载解析。换句话说,super 只是一种语义,可以调用超类中的方法,即使当前类中存在相同的方法。

    换句话说(稍微简化),super 将内存位置视为超类的实例(例如,您子类化的类型,通常是NSObject),而self 将内存位置视为指向您定义的类型的常规指针。

    如果您在调试器中打印superself,您将看到它们指向同一个内存位置。

    【讨论】:

    • 太棒了!这就是我一直在寻找的......所以我的自我 :-) 很好,但我也很优秀?我虽然超级会是超类?即 NSObject?
    • so self = [super init];现在 self 等于我的 NSObject 超类,或者它等于我,但这就是我感到困惑的地方,来自 .net/java 背景。如果我调用我的超级类并进行初始化,那么超级实际上是 nsobject 不是吗
    • @Martin,我稍微更新了答案,希望它能澄清。如果您有一个继承 NSObject 的类 Foo,那么 Foo 也是 NSObject - is-a 关系。 selfsuper 指向同一个内存,但解析时处理不同。
    【解决方案2】:

    整个对象创建调用看起来有点像这样:

    SomeClass *foo = [[SomeClass alloc] initWithScore:100];
    

    现在发生的第一件事是调用[SomeClass alloc]。这将在内存中为SomeClass 创建一个结构并返回一个指向它的指针。接下来是初始化内容,其中self 是上一步的指针。因此self 指向一个类SomeClass 的对象。

    不过,这个作业看起来有点奇怪:

    self = [super init];
    

    在大多数情况下[super init] 不会改变self,它只会返回由[SomeClass alloc] 创建的指针。但是分配模式允许两个额外的选项:

    1. 超类 init 可以通过返回 nil 来表示构造错误,在这种情况下,所有后续初始化程序都会退出,您会得到一个 nil 对象。

    2. 超类初始化器可能决定返回一个不同的self 指针,例如,如果有一些复杂的缓存正在进行。指针应该再次指向SomeClass 类型的对象,这样您的代码才能正常工作(您可以访问score 等)。

    我建议您阅读 Mike Ash 的 The How and Why of Cocoa Initializers。是的,很高兴意识到 selfsuper 都指向同一个对象,正如 driis 所指出的那样。

    【讨论】:

    • 我想他还是想知道他为什么要这样做。这样做的原因是[super init] 被允许返回一个不同的指针,例如nil 如果它无法初始化自己。
    • 嗨,zoul,是的,我创建了对象,并且我理解我不明白的(参见上面有问题的代码 sn-p)是在 initiWithScore 中,self 被分配给 [super init] 所以它现在有超级并将这个超级返回给调用客户端然后调用客户端(你的代码)在返回超级时如何具有“SomeClass”的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多