2017-01-30 8 views
-1

Ich habe einige extern Variablen in @interface Block meiner .h Datei deklariert. Sie sind in .m Datei zugewiesen. In einer Methode meiner @interface (vorzuziehende Klassenmethode) möchte ich über diese Variablen per Reflexion aufzählen, aber ich habe keine Ahnung, ob das überhaupt möglich ist, und wie ist das? Beispiel meines Codes:Objektiv C Reflexion für C-Typ Vars

Consts.h 

extern NSString *MyConst1; 
extern NSString *MyConst2; 

Consts.m 

NSString *MyConst1 = nil; 
NSString *MyConst2 = nil; 

+ (void)load { 
    MyConst1 = ...; 
    MyConst2 = ...; 
} 

+ (void)someMethod { 
    // i could use class_copyIvarList for objective c properties/ivars, 
    // but is it possible to get that MyConts1 and MyConst2 via reflection ? 
    // I understand, that C have different namespace, 
    // and I have no experience with it. 
} 
+0

In C gibt es keine Reflexion. Wenn Sie Über-Werte aufzählen möchten, fügen Sie sie in ein Array ein. Wenn Sie Werte für sie festlegen möchten, listen Sie sie über Zeiger auf. – Sulthan

+0

@Sultan in Array-Anordnung ist offensichtlich. Ich bin daran interessiert, nicht viel doppelten Code zu machen. Vielleicht haben Objc etwas Laufzeitmagie für c Zeug? Es gibt Unterschiede in c vars in der @ Schnittstelle und nicht, also könnten sie irgendwie durch objc reflektiert werden? –

+0

Objective-C macht keine Magie mit C. Objective-C erstellt Objekte, die aus C-Strukturen bestehen, mit zusätzlichen Metadaten, die eine Reflexion an * Obj-C * -Objekten ermöglichen. Aber C ist nur C. – Sulthan

Antwort

0

Objective-C unterstützt Reflexion für Objective-C-Objekte. Die Reflexion funktioniert, weil jede Obj-C-Klasse die notwendigen Metadaten (Eigenschaftsnamen, Methodennamen usw.) enthält.

Objective-C ändert in keiner Weise die Sprache C. Objective-C-Laufzeit wird grundsätzlich in C implementiert, und der Compiler übersetzt Objective-C nur in C-Funktionsaufrufe.

Nein, Sie können die Reflektion für globale Variablen nicht außerhalb des Kontexts einer Objective-C-Klasse verwenden.

Wenn Sie Reflexion wollen, wickeln Sie sie in eine Klasse ein.

Beachten Sie jedoch, dass die Verwendung von Reflexion fast nie eine gute Lösung ist. Normalerweise wird es missbraucht, um ein Problem zu lösen, das durch schlechte Architektur verursacht wird.

0

In ObjC gibt es keine Klassenvariablen. Nur Instanzen können Variablen in ObjC enthalten. Selbst wenn Sie ein globales Interface zwischen @interface oder @implementation und @end deklarieren, wird es immer noch ein globales sein, ObjC weiß es eigentlich nicht.

Nur die ObjC-Teile in einer .m-Datei unterstützen die Introspektion. Ein alternativer Ansatz bestünde darin, ein Singleton zu erstellen, das über Methoden verfügt, die die Konstanten zurückgeben. Anschließend können Sie ihre Methoden aufzählen. Alternativ könnten Sie eine Funktion/Methode erstellen, die ein Array Ihrer Konstanten zurückgibt. Um Doppel Ihre Konstanten und Arrays zu vermeiden, könnten Sie die X-Makro-Technik verwenden:

#define OSC_TYPE_CONSTANTS X(MyConst1) \ 
          X(MyConst2) 

// Header: 
#define X(n) extern NSString* n; 
OSC_TYPE_CONSTANTS 
#undef X 

// Implementation: 
#define OSC_STRINGIFY(n) #n 
#define X(n) NSString* n = OSC_STRINGIFY(n); 
OSC_TYPE_CONSTANTS 
#undef X 

#define X(n) n, 
NSArray* gAllTypesArray = [NSArray arrayWithObjects: OSC_TYPE_CONSTANTS nil]; 
#undef X 

Was brauchen Sie das? Sind diese Konstanten direkt in Ihrer App kompiliert, oder ist dies in einem Framework, aus dem sie exportiert werden? Abhängig davon kann es Lösungen mit CFBundleGetDataPointerFromName oder dlsym von CFBundle geben.