Objective-C中的"超级"是什么?(自我!=超级)?

Dav*_*son 8 iphone macos objective-c ios

我已经阅读了下面的问题,故事SEEMS很简单:

在Objective-C中究竟是什么超级?

然而......

- (id) init
{
    NSLog(@"self=%p, super=%p", self, super);
}
Run Code Online (Sandbox Code Playgroud)

打印出"self = 0xa83dc50,super = 0xbfffe8d0".地址不是相同的???!?!?

第二个地址似乎是"特殊价值"或其他东西.这是什么意思?

感谢bbum指出这个值是编译器用来实现"超级"行为的特殊结构的堆栈地址.


我可以打电话给[super init],这个电话似乎有效,或者至少没有任何东西爆炸......不是立刻.使用EXC_BAD_ACCESS调用[((id)0xbfffe8d0)init]失败.

然后是真正的WEIRD部分.....我有一段代码,由于没有可解释的原因抛出"NSGenericException:集合在枚举时被突变"异常.在DIFFERENT对象内部(基本上是一个包含指向NSEnumerator的指针的包装器),注释掉对"[super init]"的调用会导致异常不发生.如果可以的话,我会为这个心灵弯曲的答案提出一个$$$奖励.

"id sups =(id)0xbfffe8d0"......这也导致"集合被修改"....... WTF?好的,所以我发布了第二个问题,因为那个bizzariotity ...


我最初来到这里的一个"奇怪的症状"错误,结果证明完全不相关(典型的这类事情):铸造一个地址(ID)有副作用??? 地址0xbfffe8d0特殊吗?(修复:问题是_NSCallStackArray)

但是,该行上方的内容仍然有效,响应仍然很好.如果你想更深入地了解ObjC,请阅读它.

bbu*_*bum 15

你正在弄乱幕后的男人,他正在惩罚你...... :)

super是真的,有点编译魔术.当你说[super doSomething],编译器将发出一个调用objc_msgSendSuper()而不是objc_msgSend().大多数时候 - 有一些特殊情况.

通常,您应该将其super视为方法调用的目标.它不应该被存储在任何地方不应该被认为是什么,但对于短信这一目标的表达.

实际上,super编译器可能会标记涉及存储的使用.

就你的错误而言,这听起来很糟糕,就像存在内存损坏,过度释放和/或并发一样.您需要提供更多与枚举相关的代码和其他相关代码以进一步推断.

  • 如果你感兴趣的话,`super`被实现(或曾经是)作为指向结构的指针.该结构包含两个元素,第一个是`self`,第二个是超类,它告诉运行时哪个类开始查找. (6认同)
  • 对; 如果你要查看程序集,编译器放下所述结构,然后`objc_msgSendSuper()`使用`superclass`的`isa`来启动方法搜索,同时使用struct对`self`的引用作为目标方法调用.一个实现细节(感谢@ughoavgfhw去那里!!). (2认同)