2012-04-01 53 views
8

我读过下面的问题,故事似乎简单什么是Objective-C中的“super”? (自我!=超级)?

What exactly is super in Objective-C?

然而...

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

打印出 “自我= 0xa83dc50,超级= 0xbfffe8d0” 。地址不一样???!?!?

第二个地址看起来像是“特殊值”或什么的。这是什么意思?

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


我可以调用[超级的init]和呼叫似乎工作,或者至少,没有爆炸......不会立即进行。调用[((id)0xbfffe8d0)init]会导致EXC_BAD_ACCESS失败。

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

“id sups =(id)0xbfffe8d0”...这也导致“收集被修改”。 ... WTF?好了,所以我张贴为bizzariotity第2个问题...


我最初来到这里与那些“怪异symtoms”的错误,这竟然是完全不相干的一个(典型的这样的事情) :Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

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

+2

除了你的其他问题,0xbfffe8d0大概是一个代码地址,但没有理由期望从一个编译到另一个编译都是一样的。将该字面值转换为指针基本上只是从随机数中创建一个指针。 – 2012-04-01 03:31:50

+0

实际上,它是一个堆栈地址,与代码地址不同。从一次跑到下一次都不一样! – 2012-07-16 17:28:10

+0

在同一次运行中,从一个瞬间到另一个瞬间,堆栈地址并不相同。 – 2012-07-16 20:48:40

回答

15

您与幕后的人搞乱,他是在惩罚你吧... :)

super是有点神奇的编译器,真的。当你说[super doSomething]时,编译器将发出呼叫objc_msgSendSuper()而不是objc_msgSend()。大多数时候 - 有一些特殊情况。

一般而言,您应该将super视为仅限方法调用的目标。它永远不应该存储在任何地方,不应该被认为是任何东西,但目标为消息传递的表达式。

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

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

+0

heh,“与幕后男子混淆”:)我发布了第二个问题,提供了有关该错误的更多详细信息。 – 2012-04-01 03:19:59

+6

如果你有兴趣,'super'被实现(或曾经是)作为指向结构的指针。该结构包含两个元素,第一个是'self',第二个是超类,它告诉运行时哪个类开始查找。 – ughoavgfhw 2012-04-01 05:33:44

+0

AH!这解释了奇怪的价值。这是你提到的那个时髦结构的堆栈地址。 Yup; – 2012-04-01 18:26:00

相关问题