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

时间:2022-03-10 02:42:56

I've read the question below, and the story SEEMS simple:

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

What exactly is super in Objective-C?

Objective-C究竟是什么超级?

Yet ...

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

That prints out "self=0xa83dc50, super=0xbfffe8d0". The addresses are NOT THE SAME???!?!?

打印出“self = 0xa83dc50,super = 0xbfffe8d0”。地址不是相同的???!?!?

That second address seems like a "special value" or something. What does it mean?

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

Thanks to bbum for pointing out that this value is the stack address of a special struct used by the compiler to implement the "super" behavior.

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


I can call [super init] and the call seems to work, or at least, nothing explodes ... not immediately. Calling [((id)0xbfffe8d0) init] fails hard with EXC_BAD_ACCESS.

我可以调用[super init]并且呼叫似乎有效,或者至少没有爆炸......不是立即。使用EXC_BAD_ACCESS调用[((id)0xbfffe8d0)init]失败。

Then there is the REALLY WEIRD part..... I've got a piece of code that for no explainable reason throws a "NSGenericException: collection was mutated while being enumerated" exception. Inside a DIFFERENT object (basically a wrapper that has a pointer to the NSEnumerator), commenting out the call to "[super init]" causes the exception to not happen. If I could, I'd put out a $$$ reward for an answer to THAT mind-bender.

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

"id sups = (id)0xbfffe8d0" ... that also leads to "collection is modified." ... WTF? Ok, so I'm posting a 2nd question for that bizzariotity ...

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


I originally came here with one of those "bizarre symtoms" bugs, that turned out to be entirely unrelated (typical for such things): Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

我最初带着其中一个“奇怪的症状”错误来到这里,结果证明是完全不相关的(这类事情很典型):将地址转换为(id)会产生副作用吗?地址0xbfffe8d0特殊吗? (修复:问题是_NSCallStackArray)

However, the content above the line is still valid, and the response still excellent. Read it if you want to understand ObjC just a little bit deeper.

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

1 个解决方案

#1


15  

You are messing with the man behind the curtain and he is punishing you for it... :)

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

super is a bit of compiler magic, really. When you say [super doSomething], the compiler will emit a call to objc_msgSendSuper() instead of objc_msgSend(). Most of the time -- there are some special cases.

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

In general, you should treat super as only a target for method calls. It should never be stored anywhere and should never be considered anything but that target expression for messaging.

通常,您应该将super视为方法调用的目标。它永远不应存储在任何地方,除了用于消息传递的目标表达式之外,不应该被视为任

In fact, uses of super that involve storage should likely be flagged by the compiler.

实际上,编译器可能会标记涉及存储的超级用途。

In terms of your bug, that sounds an awful lot like there is either corruption of memory, an over-release, and/or concurrency going on. You'll need to provide more code related to the enumeration and other relevant code to deduce further.

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

#1


15  

You are messing with the man behind the curtain and he is punishing you for it... :)

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

super is a bit of compiler magic, really. When you say [super doSomething], the compiler will emit a call to objc_msgSendSuper() instead of objc_msgSend(). Most of the time -- there are some special cases.

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

In general, you should treat super as only a target for method calls. It should never be stored anywhere and should never be considered anything but that target expression for messaging.

通常,您应该将super视为方法调用的目标。它永远不应存储在任何地方,除了用于消息传递的目标表达式之外,不应该被视为任

In fact, uses of super that involve storage should likely be flagged by the compiler.

实际上,编译器可能会标记涉及存储的超级用途。

In terms of your bug, that sounds an awful lot like there is either corruption of memory, an over-release, and/or concurrency going on. You'll need to provide more code related to the enumeration and other relevant code to deduce further.

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