2013-03-09 9 views
9

Betrachtet man den Quellcode der Objective-C-Laufzeitbibliothek, insbesondere unter objc-runtime-new.mm, sah ich einige Funktionen und sogar Kommentare, die sich auf faule und nicht-faule Klassen bezogen. Es scheint, dass Klassen, die keine +load Methode haben, faule Klassen genannt werden, aber ich bin mir nicht sicher, und das ist wahrscheinlich nicht richtig. Nach der Suche auf Google habe ich nichts über faule Klassen auf Objective-C gefunden.Objective-C: Was ist eine faule Klasse?

Also, was ist eine faule Klasse in Objective-C? Hat Obj-C diese Funktion? Bezieht sich dies auf das Vorhandensein einer +load-Methode in einer Klassenimplementierung? In der oben verlinkten Datei ruft das Laufzeitsystem eine Funktion mit dem Namen _getObjc2NonlazyClassList auf, um eine Liste von nicht faulen Klassen aus einem Bild zu erhalten. Warum gibt es keine _getObjc2LazyClassList Funktion?

+0

könnte eine Klasse sein, die von einem Plugin geladen wurde. vielleicht überprüfen Sie die Dokumentation auf Plugins/dyld/dynamisch geladenen Code – nielsbot

+0

Sind Sie sicher, dass es bedeutet, dass die Klasse faul ist und nicht nur die Liste? –

+0

Ich stimme @JoshCaswell zu, da später in der Laufzeitquelle Verweise auf das Laden in den Klassen stehen. Es bezieht sich eher auf die Liste, als dass eine Klasse "faul" ist. – lxt

Antwort

11

Ich fand die Antwort: Es geht um eine Klasse implementieren oder nicht eine +load Methode.

Alle Klassen, die in einer gegebenen Bilddatei implementiert sind, haben eine Referenz in einer Liste, die in der "__DATA, __objc_classlist, regular, no_dead_strip" Sektion gespeichert ist.Diese Liste ermöglicht dem Laufzeitsystem, alle in einer solchen Datei gespeicherten Klassen zu verfolgen. Es müssen jedoch nicht alle Klassen beim Start des Programms realisiert werden. Wenn eine Klasse eine +load-Methode implementiert, verfügt sie daher auch über eine Referenz in einer Liste, die im Abschnitt "__DATA, __objc_nlclslist, regular, no_dead_strip" gespeichert ist.

So, _getObjc2NonlazyClassList ruft die Liste der Klassen, die eine +load-Methode implementieren und sind so genannte nicht faul. _getObjc2ClassList ruft eine Liste aller Klassen in einer Image-Datei ab, einschließlich der Klassen, die keine +load-Methode haben (und die als träge bezeichnet werden) und die nicht-faulen. Nicht-faule Klassen müssen beim Start des Programms realisiert werden. Lazy Klassen müssen nicht sofort realisiert werden. Dies kann verzögert werden, bis die Klasse zum ersten Mal eine Nachricht empfängt (das ist der Grund, warum sie als "faul" betrachtet werden).

Das gleiche gilt übrigens für Kategorien.

+0

Beachten Sie, dass Sie für Kategorien das 'all_load' Linker-Flag verwenden müssen, wenn sich diese Kategorien in einer externen Bibliothek befinden. –

+0

Das mag nahezu korrekt sein, aber ich habe MachO-Bilder gesehen, die eine __objc_nlclslist enthalten, aber keinen __objc_classlist-Abschnitt enthalten. – jsears

5

"Lazy" wird in zwei verschiedenen Kontexten verwendet.

Die erste, wenn ein Klassenentwurf kritisiert wird, argumentiert, dass eine Klasse unwirksam ist - dass sie nicht genug tut, um ihre Existenz zu rechtfertigen. Die Leute nennen diese Art von Klasse auch "dünn". Das ist wahrscheinlich nicht das, was du hier meinst.

Zweitens lazy evaluation und faul Instanziierung bedeuten, dass die Klasse nicht nur die Arbeit der eine Eigenschaft Auswertung oder selbst zu initialisieren, wenn sie tatsächlich benötigt werden.

Angenommen, wir haben eine Klasse, die ein Employee-Objekt erstellt.

Das ist in Ordnung, aber das Abrufen aller Datensätze aus einer Datenbank ist möglicherweise langsam. Und manchmal müssen wir die Arbeit nicht machen. Zum Beispiel:

- (BOOL) isFounder 
{ 
    if (indent.number<10) return YES; 
    return NO; 
} 

Wenn wir einen Mitarbeiter einfach sind instanziieren, um herauszufinden, ob sie ein Gründer sind, wir tun müssen, um ihre Aufzeichnungen nicht sehen überhaupt nicht!

..... 
if ([thisEmployee isFounder]) { 
     [self sendCandyTo: thisEmployee.identification]; 
     } 

Auf der anderen Seite, manchmal müssen wir sie:

- (NSArray*) payments 
{ 
    return [self.records retrievePayStubs]; 
    } 

Also, wenn wir nur ein Angestellter sind konstruieren isFounder zu nennen, haben wir eine Datenbanksuche verschwenden. Aber wir können das nicht einfach überspringen, weil payments es braucht.

Was wir tun, ist die Datenbank suchen aus dem Konstruktor und legte es in eine load Methode.

- (void) load 
{ 
    if (records) return; 
    self.records=[self retrieveEmployeeRecordsFor: ident]; 
} 

- (NSArray*) payments 
{ 
    [self load]; 
    return [self.records retrievePayStubs]; 
    } 

Jetzt laden wir nur die Mitarbeiterdatensätze, wenn wir sie tatsächlich brauchen. Wenn sie bereits geladen wurden, führen wir (abgesehen von einem Methodenaufruf) keine zusätzliche Arbeit aus. Wenn wir die Zahlungsaufzeichnungen nie brauchen, müssen wir die Arbeit überhaupt nicht machen.

Die Klasse funktioniert nur, wenn sie muss - und wartet bis zur letzten Minute, um die Arbeit zu erledigen. Es ist "faul"!

+0

Danke für die Antwort, Mark. Das habe ich mir vorgestellt. Eine Klasse wird also wegen ihres Verhaltens als "faul" angesehen. Aber etwas stört mich immer noch: die Existenz der Funktion "_getObjc2NonlazyClassList", die anscheinend Klassen lädt, die in der Bilddatei als nicht-faul gespeichert sind. Es ist, als gäbe es einen Aspekt, der eine Klasse zur Kompilierzeit nicht-faul macht. Oder vielleicht ist es nur Nomenklatur: Alle aus einer Bilddatei geladenen Klassen gelten als nicht-faul ... – LuisABOL