Apakah mungkin untuk membuat instance kelas dengan nama? Sesuatu seperti:
NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];
Saya tidak tahu apakah ini mungkin dalam obyektif-c tetapi sepertinya akan,
Jawaban:
id object = [[NSClassFromString(@"NameofClass") alloc] init];
NSClassFromString()
menjalankan risiko salah ketik nama kelas atau sebaliknya menggunakan kelas yang tidak ada. Anda tidak akan mengetahuinya sampai runtime jika Anda membuat kesalahan itu. Sebaliknya, jika Anda menggunakan tipe objektif-c bawaan Class
untuk membuat variabel, maka compiler akan memverifikasi bahwa kelas tersebut ada.
Misalnya, di .h
:
@property Class NameOfClass;
dan kemudian di .m
:
id object = [[NameOfClass alloc] init];
Jika Anda salah mengetik nama kelas atau jika tidak ada, Anda akan mendapatkan kesalahan pada waktu kompilasi. Juga saya pikir ini adalah kode yang lebih bersih.
Jika Anda bekerja dengan Objective-C tanpa NeXTstep
( OS X
, iOS
, GNUstep
dll) sistem atau Anda hanya berpikir metode ini lebih bersih, maka Anda bisa memanfaatkan bahasa Objective-C runtime perpustakaan API . Di bawah 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 ];
Di bawah Objective-C (1.0 atau versi tanpa nama) Anda akan menggunakan yang berikut:
#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 ];
Saya belum menguji 1.0
versinya, namun saya telah menggunakan 2.0
fungsi dalam kode yang sekarang dalam produksi. Saya pribadi percaya menggunakan 2.0
fungsi lebih bersih jika tersedia daripada fungsi NS karena mengkonsumsi lebih sedikit ruang: the length of the name in bytes + 1 ( null terminator )
untuk 2.0 API versus the sum of two pointers (isa, cstring)
, a size_t length (cstring_length)
, dan length of the string in bytes + 1
untuk NeXTSTEP
API.