2008-11-24 8 views
15

Nesnelerin küçük bir koleksiyonunu takip etmek için bir nesne fabrikasında çalışıyorum. Nesneler farklı tiplerde olabilir, ancak hepsi createInstance ve reset'a cevap verecektir. Nesneler ortak bir taban sınıfından türetilemez, çünkü bazılarının NSView ve NSWindowController gibi dahili kakao sınıflarından türetilmesi gerekecektir.Kakaoda bir nesne fabrikasına argüman olarak bir sınıf adını nasıl geçirebilirim?

Ben şöyle sadece benim fabrikaya istenen sınıfadı ileterek uygun olan herhangi bir nesne örneklerini oluşturmak mümkün olmak istiyorum

:

myClass * variable = [factory makeObjectOfClass:myClass];

makeObjectOfClass: yöntem şöyle görünecektir:

- (id)makeObjectOfClass:(CLASSNAME)className 
{ 
    assert([className instancesRespondToSelector:@selector(reset)]); 
    id newInstance = [className createInstance]; 
    [managedObjects addObject:newInstance]; 
    return newInstance; 
}

makeObjectOfClass: numaralı (CLASSNAME)className argümanında yaptığım gibi, bir yönteme bir sınıf adı iletmenin bir yolu var mı?

Bütünlük adına, bu yüzden tüm nesneleri yönetmek istiyorum. [factory reset]; numaralı telefonu arayarak, bir nesnede tam bir nesne setini sıfırlayabilmek istiyorum. +createInstance adında bir sınıf yöntemi varsayılabilir

- (id)makeObjectOfClassNamed:(NSString *)className 
{ 
    Class klass = NSClassFromString(className); 
    assert([klass instancesRespondToSelector:@selector(reset)]); 
    id newInstance = [klass createInstance]; 
    [managedObjects addObject:newInstance]; 
    return newInstance; 
} 

Bu:

- (void)reset 
{ 
    [managedObjects makeObjectsPerformSelector:@selector(reset)]; 
}
+0

ödeme lütfen. İkisinden de bahsettim, çünkü her ikisi de aradığım şey olan 'Sınıf' kullanımından bahsetmişti. Sonunda, Matt'in cevabını seçtim çünkü ClassFromString üzerinde 'Class'ı vurgular, ve düzenlemeden önce' Class 'kullanımını kullanan ilk kişi oldu. –

+0

@Ned Batchelder: Etiketi değiştirdiğiniz için teşekkür ederiz. Bir nedenden dolayı, 'objectivec' soruna etiket eklediğimde beliren etiketlerin aşağı açılan listesinde 'objektif-c' den çok daha fazla öğe (200 civarında) gösterir, ancak şimdi 'objectivec'in yeniden yönlendirildiğini görüyorum. 'objektif-c' –

+0

@eJames: Sorunuz, sınıf nesnesine değil, örneklere gönderilmeyi gösterir. Bu yüzden, Matt Gallagher'ın yanıtındaki [aClass yanıtıToSelector: @selector (sıfırlama)] 'nın yanlış olduğunu düşünüyorum. –

cevap

22

Sen işlevini kullanarak bir sınıfa bir dize dönüştürebilirsiniz: olsa durumda

Class classFromString = NSClassFromString(@"MyClass"); 

NSClassFromString, Sınıf nesneleri doğrudan kullanarak daha iyi olurdu.

MyClass * variable = [factory makeObjectOfClass:[MyClass class]]; 

- (id)makeObjectOfClass:(Class)aClass 
{ 
    assert([aClass instancesRespondToSelector:@selector(reset)]); 
    id newInstance = [aClass createInstance]; 
    [managedObjects addObject:newInstance]; 
    return newInstance; 
} 
+0

'Class' türü ve [MyClass sınıfı] tam olarak aradığım şey. Teşekkür ederim! –

+0

Michael Tsai [aClass yanıtınıToSelector: @selector (reset)] satırında [aClass instancesRespondToSelector: @selector (reset)] yazması gerektiğini belirtti. Soruda değişiklik yapıyorum, cevabınızda aynısını yapmak isteyebilirsiniz. –

2

Bu gibi bir şey istemek gibi geliyor. Ya da sadece [[klass alloc] init]'u kullanabilirsiniz.

diyoruz için:

MyClass *variable = [factory makeObjectOfClassNamed:@"MyClass"]; 

sen daha iyi olabilir yapmaya çalıştığımız şeye bağlı dizeleri daha sınıf nesneleri, örneğin etrafında geçmek:

MyClass *variable = [factory makeObjectOfClass:[MyClass class]]; 
+0

Cevabınız için teşekkür ederiz. Düzenlemede bahsettiğiniz [MyClass sınıf] yaklaşımını kullanacağım. –

+0

Objective-C++ için derlemedığınız sürece, "class" değişkenlerini adlandırabilirsiniz. NSManagedObject hakkında – cncool

3

Bu oldukça kolaydır Dinamik olarak bir sınıf belirtebilirsiniz, aslında bu isimle sadece başvuruda bulunabilirsiniz:

id string = [[NSClassFromString(@"NSString") alloc] initWithString:@"Hello!"]; 
NSLog(@"%@", string); 

Diğer bir ipucu Diğer çoğu Kakao programcısı, Core Data'dan NSManagedObject olarak okuyacağından, 'yönetilen nesne' isimlendirmesini kullanarak geçersizdir. Ayrıca, farklı türde nesnelerin bir koleksiyonunu yönetmek yerine global bir NSNotification (tüm sıfırlanabilir nesnelerinizin abone olduğu) kullanımını daha kolay bulabilir, ancak bu kararı verdiğimden daha fazla bilgilendirebilirsiniz.

+0

iyi nokta. Olası karışıklığı önlemek için sorumu değiştireceğim. –

3

diğer cevaplar eksik cevabın biraz size +createInstance ve +reset yöntemleri içeren bir @protocol tanımlayabiliriz olmasıdır.

+0

Bahşiş için teşekkürler! Bir protokol kullanmayı planlıyorum ama soruda bahsetmeye gerek duymadım. –

İlgili konular