2012-04-01 9 views
8

私は質問以下読んで、そして物語簡単なようだ:Objective-Cでは "super"とは何ですか? (自己!=スーパー)?

What exactly is super in Objective-C?

しかし...を "自己= 0xa83dc50、スーパー= 0xbfffe8d0" を出力します

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

。アドレスは同じではありませんか?!?!?

この2番目のアドレスは「特別な価値」などと思われます。どういう意味ですか?

この値は、「スーパー」動作を実装するためにコンパイラによって使用される特別な構造体のスタックアドレスであることを指摘してくれたBBCに感謝します。


私は[スーパーのinit]呼び出すことができますし、呼び出しが動作しているようです、または少なくとも、何もない、すぐに...爆発ません。 [((id)0xbfffe8d0)init]を呼び出すと、EXC_BAD_ACCESSで失敗します。

私は説明できない理由のために "NSGenericException:コレクションが列挙されている間に突然変異が起こった"という例外をスローするコードを持っています。 DIFFERENTオブジェクト(基本的には、NSEnumeratorへのポインタを持つラッパー)内で、「[super init]」の呼び出しをコメントアウトすると例外が発生しません。私ができるなら、私はその心のベンダーへの答えに$$$の報酬を出すでしょう。

「id sups =(id)0xbfffe8d0」...「コレクションは変更されています。」 ... WTF? [OK]を、ので、私はもともと(のようなものの典型的な)完全に無関係であることが判明したもの「奇妙なsymtoms」のバグの一つ、とここに来た...


をそのbizzariotity第2回質問を投稿しています:Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

しかし、行の上の内容はまだ有効であり、応答はまだ優れています。あなたがObjCをちょっと深く理解したいのであれば、それを読んでください。

+2

他の問題とは別に、0xbfffe8d0はおそらくコードアドレスですが、あるコンパイルから次のコンパイルまで同じであると予想する理由はありません。リテラル値をポインタにキャストするのは、基本的に乱数からポインタを作成することです。 –

+0

実際には、スタックアドレスであり、コードアドレスと同じではありません。 1つの実行から次の実行まで同じではありません! –

+0

スタックアドレスは同じ実行で同じ瞬間から次の瞬間まで同じではありません。 –

答えて

15

あなたはカーテンの後ろに男をいじりされ、彼はそれのためにあなたを罰するされて... :)

superは本当に、コンパイラの魔法のビットです。 [super doSomething]と言うと、コンパイラはobjc_msgSend()の代わりにobjc_msgSendSuper()を呼び出します。ほとんどの場合、特殊なケースがいくつかあります。

一般に、superとして扱い、というメソッド呼び出しのターゲットのみを扱う必要があります。どこにも格納するべきではなく、何もメッセージとして扱われるべきではないと考えられるべきではありません。しかし

実際には、ストレージを含むsuperの使用には、コンパイラによってフラグが立てられているはずです。

バグの面では、メモリの破損、過剰リリース、並行処理のいずれかが起こっているように思えます。列挙に関連するコードや関連する他のコードをさらに推論する必要があります。

+0

heh、 "カーテンの後ろにいる男を悩ませている" :)私はそのバグの詳細について2番目の質問を投稿しました。 –

+6

興味があれば、 'super'は構造体へのポインタとして実装されています。構造体には2つの要素が含まれていました。最初の要素は 'self'でした。2番目の要素はスーパークラスでした。実行時にクラスを調べ始めるように指示しています。 – ughoavgfhw

+0

AH!それは奇妙な価値を説明します。これは、あなたが言及したその厄介な構造体のスタックアドレスです。 –

関連する問題