2012-08-07 1 views
5

In der Vorgängerversion von Objective-C wird eine objc_class Struktur wie folgt implementiert:Wie werden Instanzvariablen und Methoden in einem Objective-C 2.0-Objekt gespeichert?

struct objc_class { 
    Class isa; 
    Class super_class; 
    const char *name; 
    long version; 
    long info; 
    long instance_size; 
    struct objc_ivar_list *ivars; 
    struct objc_method_list **methodLists; 
    struct objc_cache *cache; 
    struct objc_protocol_list *protocols; 
}; 

So ist die Struktur, die speichert einen Zeiger auf die Klasse des Objekts ein Objekt darstellt, einen Zeiger auf denen das Superklasse des Objekts , den Klassennamen des Objekts, die Version des Objekts, die Informationen und die Instanzgröße, die Liste der Instanzvariablen des Objekts, die Methodenliste des Objekts, den Cache des Objekts und die Protokollliste des Objekts. Das Vorhandensein dieser Felder in der Struktur, die ein Objekt darstellt, ist ziemlich verständlich, da jede von ihnen eine Information über das Objekt speichert.

jedoch die Objective-C 2.0-Implementierung der gleichen Struktur objc_class ist wie folgt:

struct objc_class { 
    Class isa; 
}; 

Also, in dieser Version von objc_class, gibt es nur ein Feld in der Struktur: ein Zeiger auf das Objekt Klassenstruktur

Meine Frage ist dann, wie sind die anderen Informationen über das Objekt in Objective-C 2.0 gespeichert, da es nur ein Feld in der Struktur gibt, die die Objekte darstellt?

+3

Interessante Lektüre: [\ [Objc zu erklären \]: Nicht-fragile Ivars] (http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html) –

Antwort

7

Es ist alles in der neuen (ok, nun nicht so neu) nicht fragilen ABI.

Im Grunde, anstatt iVars innerhalb einer Struktur wie gewohnt zu speichern (die Vererbung brechen würde, wenn eine Oberklasse ihr iVar-Layout geändert hat), setzt der Compiler iVar Umleitung durch eine andere Schicht, ähnlich objc_setAssociatedObject zur Laufzeit.

Dies ermöglicht ein paar interessante Szenarien. Beachten Sie Folgendes:

@interface A { // part of libA.a 
    id var1; 
    int var2; 
    float var3; 
} 

@end 

@interface B : A { // part of libB.a 
    id var4; 
} 

@end 

Nun, was ist, wenn einige Zeit auf der Straße, müssen wir Klasse ändern A, und wir bestimmen wir mehr Präzision benötigen in var3 (Umwandlung in einen long double, zum Beispiel)?

In der älteren, zerbrechlichen ABI, würden wir bis zum Hersteller von libB aktualisiert werden. Mit diesem neuen, nicht zerbrechlichen ABI haben wir die Flexibilität, all dies zu ändern, während libB immer noch funktioniert.

Während dies in der Theorie um einige Zyklen langsamer sein kann, bietet es einfachere Möglichkeiten zur Suche nach iVars zur Laufzeit, flexiblere Unterklassen und Unterstützung für verschiedene Arten von iVars (z. B. __weak).

+0

Ok. Also, in der "neuen" Version von Objective-C, anstatt die Struktur in Kompilierzeit zu füllen, werden die Objekte Ivars und Methoden in der Laufzeit von Funktionen wie 'class_addIvar' und' class_addMethod' gespeichert? – LuisABOL

+0

@laboleite für alle Absichten und Zwecke, ja, sie sind. In Wirklichkeit werden sie immer noch als Struktur gespeichert, aber ihr Offset variiert. –

+0

Aber diese Strukturen gehören zum Laufzeitsystem und werden von den oben genannten Funktionen erfüllt, oder? – LuisABOL

Verwandte Themen