2010-02-09 15 views
18

Warum gibt NSClassFromStringnil zurück? Gemäß der Definition muss der Klassenname zurückgegeben werden. Wie sollte ich darauf achten, dieses Problem zu beheben? Ich muss eine Klasse aus String instanziieren und die Methode, die in der Klasse ist, mit der erstellten Instanz aufrufen. DieseNSClassFromString gibt null zurück

ist, wie mein Code wie folgt aussieht:

id myclass = [[NSClassFromString(@"Class_from_String") alloc] init]; 
[myclass method_from_class]; 

Aber die method_from_class Funktion wird nicht aufgerufen wird, wird die Steuerung geht nicht hinein. Und mein Code ist fehlerfrei. Irgendeine Idee, wie man das in Objective-C löst?

+2

Schauen Sie sich http://stackoverflow.com/questions/1634644/create-a-class-at-runtime-why-do-nsclassfromstring-and-objcgetclass-return-nil –

+26

* Mein Code ist fehlerfrei *, das ist ein netter. :) –

+1

:) :) aber ohne meinen Zweck zu dienen :( – suse

Antwort

29

The Documentation for the function says:

Rückgabewert Die Objektklasse mit dem Namen von aClassName oder nil, wenn keine Klasse von diesem Namen wird zur Zeit geladen. Wenn aClassName null ist, wird NULL zurückgegeben.

Ein Beispiel dafür, wie diese richtig verwendet werden soll, ist wie folgt:

Class dictionaryClass = NSClassFromString(@"NSMutableDictionary"); 
id object = [[dictionaryClass alloc] init]; 
[object setObject:@"Foo" forKey:@"Bar"]; 
+0

Aber der Wert in der Zeichenfolge @ "Class_from_String" hat den Wert des Klassennamens. Weil ich es gerade oben gedruckt habe, bevor die Klasse von String instanziiert. Dann Wie kommt es, dass es als null gilt? – suse

+0

hey 1've dritten Zeile geschrieben als: *** [Objekt TestMethod]; *** TestMethod ist die Methode in der gleichen Klasse, aber das Steuerelement geht nicht in die Methode Definition. – suse

+0

wat sollte ich tun.plz tel mir eine Alternative – suse

1

Warum all diese Anrufe nicht zersetzen? Auf diese Weise können Sie die Werte zwischen den Anrufen überprüfen:

Class myclass = NSClassFromString(@"Class_from_String"); 
id obj = [[myclass alloc] init]; 
[obj method_from_class]; 

By the way, ist method_from_class eine Instanzmethode oder eine Klassenmethode? Wenn es die später ist, dann können Sie direkt method_from_class auf dem myclass Wert nennen:

[myclass method_from_class]; 
+0

"Ist übrigens method_from_class eine Instanzmethode oder eine Klassenmethode?" Nun, wenn es keine Instanzmethode war, sollte sein Code abstürzen. – newacct

+0

Guter Ort in der Tat. –

36

Wenn Sie versuchen, eine Klasse aus einer statischen Bibliothek zu instanziiert, müssen Sie die „-ObjC“ Flagge „Sonstige hinzufügen Linker Flags "Build Einstellung.

+0

Fügen Sie dieses Flag der statischen lib oder dem Hauptprogramm hinzu, das die statische lib verwendet? – NeilJiang

+3

Arbeitete für mich Einstellung im Hauptprogramm. – micahp

+1

Sie sind fantastisch! Rettete mein Leben! :) Vielen Dank. – defactodeity

0

Ich sah auch eine Kuriosität, wo das Hinzufügen des Standard-Singleton-Codes, der von Apple unterstützt wurde, verhinderte, dass die Klasse geladen wurde. Der Code funktionierte wie erwartet, dann fügte ich den Singleton hinzu, und plötzlich begann NSClassFromString, nil zurückzuliefern. Das Auskommentieren des Singleton-Codes führte dazu, dass NSClassFromString die Klasse korrekt auflöste. Ich verstehe die Interaktion nicht, aber ich denke, die Singleton-Static-Var wurde irgendwie verstümmelt, um den Klassennamen zu verbergen ...?

2

Sie müssen auch sicherstellen, dass die Klasse, die Sie instanziieren möchten, im Projekt enthalten ist. Wenn Sie es später hinzugefügt haben, müssen Sie auf das Kontrollkästchen neben dem Ziel, das Sie erstellen, klicken.

+0

Diese Antwort funktionierte für mich. Ich habe die neue Klasse hinzugefügt, während ein anderes Ziel ausgewählt wurde. Ich musste wählen: Ziel> Build-Phasen> Compile Sources> '+', um die Klasse _really_ zum Projekt hinzuzufügen. –

4

Es ist möglich, dass Ihre Klasse nicht verknüpft wird, wenn dies der einzige Verweis darauf ist.

Ich hatte eine Factory-Methode, um verschiedene Arten von Unterklassen zu instanziieren. Die Fabrik hatte eine switch-Anweisung, die an die entsprechende Unterklasse ging und sie zuwies und initiierte. Ich habe festgestellt, dass alle alloc/init-Anweisungen bis auf den Namen der Klasse identisch waren. So konnte ich den gesamten Switch-Block mit der NSClassFromString() -Funktion eliminieren.

Ich stieß auf das gleiche Problem - die Rückkehr war Null. Der Grund dafür war, dass die Klasse an keiner anderen Stelle im Programm verwendet wurde. Daher wurde sie nicht verknüpft, sodass sie zur Laufzeit nicht gefunden wurde.

Sie können dieses Problem lösen, indem die folgende Anweisung einschließlich:

[MyClass class]; 

, dass der ganze Zweck besiegt, was ich erreichen wollte, aber es könnte alles was Sie brauchen.

4

Das ist mir passiert, wenn ich eine externe Datei zum Xcode-Projekt hinzufüge. Hinzufügen der .m-Datei zu Erstellen von Phasen>Kompilieren Quellen das Problem zu lösen.

+0

Das ist mir auch passiert, als ich die .m-Datei hinzugefügt habe, aber vergessen habe, @implementation zu schreiben –