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

时间:2012-04-01 02:54:17

标签: iphone objective-c ios macos

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

What exactly is super in Objective-C?

然而......

- (id) init
{
    NSLog(@"self=%p, super=%p", self, super);
}

打印出“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 ......


我最初带着其中一个“奇怪的症状”错误来到这里,结果证明这些错误完全不相关(典型的事情):Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

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

1 个答案:

答案 0 :(得分:15)

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

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

通常,您应将super视为仅作为方法调用的目标。它永远不应该被存储在任何地方,并且永远不应该被认为是但是那个目标表达式用于消息传递。

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

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

相关问题