【问题标题】:Is `super` local variable?`super` 是局部变量吗?
【发布时间】:2010-06-03 01:08:10
【问题描述】:
// A : Parent
@implementation A
-(id) init
{
    // change self here then return it
}
@end A

A *a = [[A alloc] init];

一个。只是想知道,如果 self 是局部变量还是全局变量?如果它是本地的,那么 self = [super init]init 中的意义何在?我可以成功定义一些局部变量并像这样使用,为什么我需要将它分配给self

-(id) init
{
    id tmp = [super init];
    if(tmp != nil) {
        //do stuff
    }
    return tmp;
}

b.如果[super init] 返回一些其他对象实例并且我必须覆盖self 那么我将无法再访问A 的方法,因为它将是全新的对象?我说的对吗?

c。 superself 指向同一个内存,它们之间的主要区别在于方法查找顺序。我说的对吗?

抱歉,没有 Mac 可以尝试,暂时学习理论...

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    Dreamlax 的回答是正确的......但是,澄清可能会有所帮助。

    一个。只是想知道,如果 self 是本地人 变量还是全局?如果是本地的话 自我的意义是什么= [超级 初始化] 在初始化?我可以成功 定义一些局部变量并使用 像这样,为什么我需要分配 给自己。

    self 不是局部变量。它是方法调用的参数。事实上,第一个论点。第二个参数是_cmd,正在执行的方法的选择器的名称。

    self 的特别之处在于,self 被编译器用来访问实例变量。也就是说,如果你说 self = [super init] 并且超类的 init 恰好返回不同的东西,那么任何进一步的实例变量访问仍然是正确的。

    b.如果 [super init] 返回一些其他的 对象实例,我必须 覆盖自我,然后我将无法 再访问​​ A 的方法,因为 它将是全新的对象吗?我是不是 对吧?

    如果 super 的 init 返回一个与 A 不兼容的实例,那么超类的设计出现了可怕的错误。请记住,Objective-C 是完全动态的。因此,没有理由超级的init 返回的任何内容实际上都需要是A 的实例,但它最好表现得像A。现在,它可能是A 子类的全新实例,因此A 的所有方法都可以正常工作。

    字里行间;请记住,Objective-C 是完全动态的。没有静态方法分派之类的东西。对象的类可以随时更改,只要新类响应该方法,任何随机方法调用仍然有效。并不是说这实际上发生在运行时,只是它可能

    c。 super 和 self 指向同一个 内存和主要区别 它们之间是方法查找顺序。 我说的对吗?

    现在,这是一个有趣的问题。 super 并没有真正指向任何东西。出于所有意图和目的,super 可以被视为其中的一点魔法。也就是说,当编译器将super 视为方法调用的目标时,它会将其编译为稍微不同的调用站点,该调用站点调用objc_msgSendSuper() 的变体之一——顾名思义——有效地“搜索" 用于从编译调用的类的父类开始的方法实现

    【讨论】:

      【解决方案2】:
      1. Self 是提供给方法实现的参数。所有 Objective-C 实例和类方法都有两个隐式参数,位于方法的参数之前。隐含的参数是self_cmd_cmd 是用于确定方法实现的选择器。

      2. 如果super 返回一个不同类的实例,那么情况就是这样,但它也有可能返回同一类的不同实例。

      3. super 是关键字,而不是变量。它通知编译器使用不同的运行时函数,从比当前类高的一个类开始方法解析。

      【讨论】:

      • 谢谢,但没有完全回答第一个问题 - 为什么我需要 self = [super init] 并且不能使用任何局部变量来完成这项工作。
      • @Michael:因为您需要调用超类的初始化程序,并且因为您的超类的初始化程序(或其超类的初始化程序)可能会返回不同的实例;如果您不更改自我,那么您将不会初始化正确的实例,并且您还将错误的实例返回给您的初始化程序。超类的初始化程序返回一个不同的实例是非常非常罕见的,因此很多人自行决定不费心将[super init] 的结果分配给self,但我个人总是这样做。这是该语言的惯用语。
      • 我不明白的是self真正改变的地方。如果self 是一个参数,那么它是通过引用传递的,所以当我更改它时,原始值也会被更改?否则,如果在返回后发生更改,在init 之外,当我实例化A 时,我可以使用tmp var 来执行此操作。
      • @Michael:在-init 内部,self 将是来自+alloc 的返回值。 +alloc 返回了一些指向某个地址的指针,该地址包含足够的空间用于所有实例变量等。运行时将+alloc 的返回值传递给-init。如果您在-init 中更改self 并返回一个不同的self,那么这个不同的self 将是在SomeClass *x = [[SomeClass alloc] init]; 语句中分配给x 的那个。
      • @dreamlax:这是合乎逻辑的,如果我从 init 返回值,它将被分配给 x。但是,我无法理解的事情......你的话中没有任何东西可以限制我使用self。我可以从-init 分配和返回任何变量,x 将取其值。
      猜你喜欢
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      相关资源
      最近更新 更多