2009-08-05 7 views
2

Ich habe ein Objekt, das mehrere Eigenschaften hat. Wenn ich einen Zeiger auf eine dieser Eigenschaften habe, ist es möglich, einen Zeiger auf die Klasseninstanz zu erhalten, zu der dieser Ivar gehört?Holen Zeiger auf Klasse der Instanzvariable in Objective-C

zum Beispiel: foo.bar, wo ich die Adresse von bar kenne, kann die Adresse von foo gefunden werden?

Dies scheint im Zusammenhang mit: run time references, aber ich habe keine Referenzen, die waren ganz, was ich gesucht.

Danke für Ihre Hilfe!

+0

Alle drei Antworten sind sehr gut. Danke Quinn, Peter und John. Ich endete Peters Lösung verwenden, indem Sie einen Zeiger auf die Objektinstanz in der Variablen "Tag" einer UIView (der Ivar ich zuvor Bezug nahm). –

Antwort

1

Zuerst müssen Sie Ihre Terminologie etwas anpassen. Sie können keinen Zeiger auf eine Eigenschaft haben, da eine Eigenschaft eine Schnittstelle zu einem Objekt ist und das Format der Getter- und Setter-Methoden angibt.

Wenn Sie einen Zeiger auf den Getter hatten, wäre eine Methode (IMP) im besten Fall ein Zeiger auf die Klasse, sicherlich konnten Sie nicht zu einer Instanz zurückkommen.

Wenn Sie einen Zeiger auf einen Ivar hatten, glaube ich nicht, dass es eine Möglichkeit gibt, zu der enthaltenden Objektinstanz zurückzukehren. Wenn Sie ein Array aller verfügbaren Foos hätten, könnte es möglich sein, jeden von ihnen nach einer Liste von Ivars zu fragen und die Adresse jedes Ivars und eventuallty zu erhalten, um die fragliche Instanz auf diese Weise zu finden.

Die beste Lösung ist, dass die Leiste einen übergeordneten Verweis auf foo enthält, damit foo.bar.foo Ihnen die gewünschte Antwort gibt. Aber es kommt darauf an, was genau du versuchst. Der normale Cocoa-Weg für viele dieser Dinge ist auch, foo zu passieren, wie es für viele Delegierte getan wird. Zum Beispiel:

1

Es sei denn, das Objekt hat einen Zeiger zurück auf seine "Eltern" oder Sie verfolgen es selbst, ich glaube nicht, dass es eine Möglichkeit gibt, das zu lösen. Du musst wirklich durch die Erinnerung gehen, um herauszufinden, was im Grunde "wer auf mich zeigt" bedeutet. Es ist im Wesentlichen das gleiche Problem wie das Finden des vorherigen Knotens in einer einfach verknüpften Liste - Sie müssen von vorne beginnen und anhalten, wenn Sie den Knoten erreichen, der auf den Knoten von Interesse zeigt.

Das Problem mit dem Versuch foo von der Adresse zu bar aufzuspüren ist, dass foo.bar ist ein Zeiger, der die Adresse eines Objekts enthält, und nur foo nennt es „bar“. Stellen Sie sich der Einfachheit halber vor, dass foo auf Adresse 0x1000 und foo.bar auf 0x1008 ist und auf ein anderes Objekt bei 0x2000 zeigt. Nun, wenn Sie die Adresse 0x2000 haben, gibt es keinen einfachen Weg zu wissen, dass 0x1008 darauf zeigt.

Es ist noch komplizierter, wenn Sie sich vorstellen, dass N andere Adressen auch auf 0x2000 zeigen könnten, also selbst wenn Sie Speicher gescannt hätten, wüssten Sie nicht, ob der Zeiger zu einem Objekt, einer Struktur, einer lokalen Variablen oder sogar gehörte nur ein zufälliges Muster, das zufällig mit der Adresse übereinstimmt, die du suchst.

0

Sie könnten es tun, wenn Sie einen Zeiger auf die Instanzvariable selbst haben, anstatt den Inhalt der Instanzvariable.

Foo * reference = [[Foo alloc] init]; 
Foo * foo == [[Foo alloc] init]; 
int * barptr = &(foo->bar); 
Foo * baz = (Foo *)((char *)barptr - ((char *)(&(reference->baz)) - (char *)reference)); 
Verwandte Themen