Czy można utworzyć instancję klasy według nazwy? Coś jak:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
Nie wiem, czy jest to możliwe w celu-c, ale wygląda na to, że tak byłoby,
Odpowiedzi:
id object = [[NSClassFromString(@"NameofClass") alloc] init];
NSClassFromString()stwarza ryzyko błędnego wpisania nazwy klasy lub użycia klasy, która nie istnieje. Nie dowiesz się do czasu uruchomienia, jeśli popełnisz ten błąd. Zamiast tego, jeśli użyjesz wbudowanego typu celu-c Classdo utworzenia zmiennej, kompilator sprawdzi, czy klasa istnieje.
Na przykład w .h:
@property Class NameOfClass;
a następnie w .m:
id object = [[NameOfClass alloc] init];
Jeśli błędnie wpisałeś nazwę klasy lub jeśli nie istnieje, pojawi się błąd w czasie kompilacji. Myślę też, że to bardziej przejrzysty kod.
Jeśli pracujesz z Objective-C bez NeXTstep( OS X, iOS, GNUstepetc) systemu lub po prostu, że ta metoda jest czystsze, a następnie można wykorzystać API Objective-C Language Runtime biblioteki . Pod Objective-C 2.0:
#import <objc/runtime.h>
//Declaration in the above named file
id objc_getClass(const char* name);
//Usage
id c = objc_getClass("Object");
[ [ c alloc ] free ];
W ramach Objective-C (1.0 lub wersja nienazwana) użyjesz:
#import <objc/objc-api.h>
//Declaration within the above named file
Class objc_get_class( const char* name);
//Usage
Class cls = objc_get_class( "Test" );
id obj = class_create_instance( cls );
[ obj free ];
Nie testowałem 1.0wersji, ale użyłem 2.0funkcji w kodzie, który jest teraz w produkcji. Osobiście uważam, że korzystanie z 2.0funkcji jest czystsze, jeśli jest dostępna, niż funkcja NS, ponieważ zajmuje mniej miejsca: the length of the name in bytes + 1 ( null terminator )dla API 2.0 w porównaniu z the sum of two pointers (isa, cstring)a size_t length (cstring_length)i length of the string in bytes + 1dla NeXTSTEPAPI.