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.