2012-12-10 5 views
5

Ich habe eine Testklasse in meinem Projekt, das es in der Entwicklungsphase ist, aber für den App Store Build kompiliert werden.Dont verstehen, wie NSClassFromString für bedingten Aufruf verwendet werden kann

Ich habe in mehreren Büchern lesen, das NSClassFromString verwendet werden kann, um zu bestimmen, ob eine Klasse mit Beispielcode wie vorhanden ist:

if (NSClassFromString(@"SomeClass") != nil) 
{ 
[SomeClass someMethod]; 
} 
else 
{ 
code not using SomeClass 
} 

jedoch danach in der Praxis in meinem Projekt setzen, finde ich, dass ich Ich bekomme einen Verknüpfungsfehler für das Ziel, wo ich die Quelldatei mit SomeClass entfernt habe.

Daher meine Schlussfolgerung ist dieser Mechanismus zur Bestimmung der Anwesenheit/Abwesenheit einer Klasse ist nur nützlich, wenn diese Klasse in einer Bibliothek oder Quelldatei ist, wo Sie andere Klassen verwenden (ein Detail, das in den Büchern fehlt, die dies erwähnen Technik). Oder fehlt mir etwas?

Antwort

6

NSClassFromString sucht die Laufzeit für die benannte Klasse. Ipso facto wird es feststellen, ob die Klasse existiert.

Für den Compiler erfolgreich Vergangenheit statische Referenzen wie [SomeClass someMethod] braucht es etwas zu verknüpfen gegen zu bekommen.

Sie haben Recht, dass der Mechanismus daher funktioniert, wenn Sie eine Verknüpfung zu etwas wie Foundation herstellen und Apple fügt dort eine zusätzliche Klasse hinzu, zum Beispiel, ob NSJSONSerialization existiert.

Es funktioniert auch, wenn Sie schwache Verbindung gegen einen Rahmen, oder nicht vorhanden sein können. So z.B. Sie könnten eine schwache Verbindung gegen Twitter.framework herstellen und [TWRequest alloc] ... verwenden. Sie könnten immer noch auf iOS 4 aufbauen und bereitstellen, wo es überhaupt kein Twitter-Framework gibt.

Apple hat tatsächlich die Art und Weise geändert, wie Bibliotheken gespeichert sind und Übergang zu ermöglichen if([TWRequest class]) oder was auch immer verwendet werden anstelle der expliziten NSClassFromString, wo Sie schwache Link.

aber in Ihrem Fall klingt es wie Sie auf eine statische Bibliothek entweder Link wollen oder nicht auf sie verwiesen wird? Also kann die Klasse zur Laufzeit verfügbar sein oder auch nicht, kann aber auch für den Linker sichtbar sein oder nicht?

In diesem Fall brauchen Sie nur wörtliche Verweise auf die Metaklasse zu vermeiden. So könnte man so etwas wie:

Class someClassMetaClass = NSClassFromString(@"SomeClass"); 

if(someClassMetaClass) 
{ 
    SomeClass *instance = [[someClassMetaClass alloc] init]; 
    /* ... */ 
} 

Solange die Header-Datei wird der Compiler glücklich sein, sichtbar ist so dass Sie den SomeClass Typen für Zeiger angeben (weil das nicht in die binären geht sowieso) und wird in der Lage sein, die üblichen Autovervollständigungen und Warnungen gegenüber der veröffentlichten Schnittstelle vorzuschlagen. Stellen Sie nur sicher, dass Sie die Metaklasse immer über einen Zeiger auf die Class adressieren, die Sie von der Laufzeit statt direkt erhalten haben. Auf diese Weise gibt es nichts, was der Linker weiterverfolgen muss.

+0

Danke. Ich baue eine Bibliothek, die "volle" und "lite" Varianten hat mit ein paar fehlenden Klassen in der lite Version. Bei einigen anderen Klassen hängt das Verhalten davon ab, ob sie vorhanden sind oder nicht. – Gruntcakes

Verwandte Themen