Ada göre objektif-c sınıfı örneği oluşturulsun mu?


95

Ada göre bir sınıf örneği oluşturmak mümkün müdür? Gibi bir şey:

NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];

Amaç-c'de bunun mümkün olup olmadığını bilmiyorum ama öyle görünüyor,

Yanıtlar:



39

NSClassFromString()sınıf adını yanlış yazma veya var olmayan bir sınıfı kullanma riskini taşır. Bu hatayı yaparsanız, çalışma zamanına kadar öğrenemezsiniz. Bunun yerine, Classbir değişken oluşturmak için yerleşik hedef-c türünü kullanırsanız, derleyici sınıfın var olduğunu doğrular.

Örneğin, sizin .h:

@property Class NameOfClass;

ve sonra sizin .m:

id object = [[NameOfClass alloc] init];

Sınıf adını yanlış yazdıysanız veya mevcut değilse, derleme sırasında bir hata alırsınız. Ayrıca bunun daha temiz bir kod olduğunu düşünüyorum.


oraya bak dostum. O iki satır gerektirir ve daha az dinamiktir, ama hepsi aynı upvoted olarak değil tamamen emin en iyi cevap, var
Chris McCall

1
Sanırım bunun daha az dinamik olduğunu söyleyebilirsin çünkü ben dizge yerine sembol kullandım. Bununla birlikte, kodu yazarken istediğiniz sınıfı biliyorsanız, olası yazım hatalarını önlemek için sembolü kullanmanız tercih edilir.
Simon Woodside

@sbwoodside: Bu nasıl işleyebilir? Bunu denedim ve bağlayıcıdan "Mimari için Tanımlanmamış semboller" aldım.
Lars Schneider

Bunu [[[kendi sınıf] ayırma] init] olarak değiştirin; Başka hiçbir şeye ihtiyacınız yok.
Nick Turner

OP'nin kullanım durumu yasal olandan daha fazlasıdır - nesne hiyerarşisinin dosya / bellek bloğu / plist / her neyse dizgeleştirmesinin temelidir. Çoğu zaman, hangi sınıfları başlatmanız gerektiğini önceden BİLMEZSİNİZ. Benim kullanım durumum, [NSValueTransformer setValueTransformer: MyTransformerA assign] init] forName: @ "MyTransformerA"] 'nın kopyalanması yerine "gazillion" NSValueTransformer "ları" kaydettirmek "için sıkıcı bir ihtiyaçtır; 40 kez - sadece bir NSArray transformatör adlarını tarıyorum - ve bunları dizeden oluşturuyor / kaydediyorum.
Motti shneor

8

Eğer olmadan Objective-C ile çalışıyorsanız NeXTstep( OS X, iOS, GNUstepvs) sistem veya sadece bu yöntem temizleyici olduğunu düşünüyorum, o zaman faydalanabilirler Objective-C dil çalışma zamanı kütüphanesinin API . Altında 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 ];

Objective-C (1.0 veya adsız sürüm) altında aşağıdakileri kullanırsınız:

#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 ];

1.0Sürümü test etmedim, ancak 2.0şu anda üretimde olan kodda işlevi kullandım . Ben şahsen kullanan inanmak 2.0daha az yer kaplar işlevini NS işlevinden daha müsait temizleyici eğer geçerli: the length of the name in bytes + 1 ( null terminator )2.0 karşı API için the sum of two pointers (isa, cstring)bir size_t length (cstring_length)ve length of the string in bytes + 1için NeXTSTEPAPI.


2
@interface Magic : NSObject
+ (id)createInstanceOfClass:(Class)classe;
@end

@implementation Magic

+ (id)createInstanceOfClass:(Class)classe
{
    return [[classe alloc] init];
}

@end

Sonra kullanmak için:

Car *car = [Magic createInstanceOfClass:[Car class]];
[car engineTurnOn];
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.