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 Class
do 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
, GNUstep
etc) 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.0
wersji, ale użyłem 2.0
funkcji w kodzie, który jest teraz w produkcji. Osobiście uważam, że korzystanie z 2.0
funkcji 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 + 1
dla NeXTSTEP
API.