我已经阅读了下面的问题,故事 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,请阅读它。
答案 0 :(得分:15)
你正在弄乱幕后的男人,他正在惩罚你...... :)。
super
真的是一些编译魔术。当您说[super doSomething]
时,编译器将发出对objc_msgSendSuper()
而不是objc_msgSend()
的调用。大多数时候 - 有一些特殊情况。
通常,您应将super
视为仅作为方法调用的目标。它永远不应该被存储在任何地方,并且永远不应该被认为是但是那个目标表达式用于消息传递。
事实上,编译器可能会标记涉及存储的super
的使用。
就你的错误而言,这听起来很糟糕,就像存在内存损坏,过度释放和/或并发一样。您需要提供更多与枚举相关的代码和其他相关代码以进一步推断。