2008-11-24 13 views
15

मैं ऑब्जेक्ट फैक्ट्री पर ऑब्जेक्ट्स के छोटे संग्रह का ट्रैक रखने के लिए काम कर रहा हूं। ऑब्जेक्ट्स विभिन्न प्रकार के हो सकते हैं, लेकिन वे सभी createInstance और reset का जवाब देंगे। ऑब्जेक्ट्स को सामान्य बेस क्लास से नहीं लिया जा सकता है क्योंकि उनमें से कुछ को NSView और NSWindowController जैसे अंतर्निर्मित कोको कक्षाओं से प्राप्त करना होगा।कोको में ऑब्जेक्ट फैक्ट्री के लिए एक क्लास नाम को तर्क के रूप में कैसे पास किया जा सकता है?

मैं इस प्रकार है बस मेरे कारखाने के लिए वांछित classname पास करके किसी भी उपयुक्त वस्तु का उदाहरण बना करने में सक्षम होना चाहते हैं:

myClass * variable = [factory makeObjectOfClass:myClass];

makeObjectOfClass: विधि कुछ इस तरह दिखेगा:

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

क्या किसी विधि को कक्षा नाम पास करने का कोई तरीका है, जैसा कि मैंने तर्क makeObjectOfClass: से ऊपर किया है?

पूर्णता के लिए, यही कारण है कि मैं सभी वस्तुओं का प्रबंधन करना चाहता हूं। मैं [factory reset]; पर कॉल करके, एक शॉट में ऑब्जेक्ट्स के पूर्ण सेट को रीसेट करने में सक्षम होना चाहता हूं।

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

यह +createInstance नाम के एक वर्ग विधि ग्रहण करेंगे:

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

मैं माइकल साई की और मैट Gallagher के जवाब के बीच फंसे रहा हूँ है। मैंने दोनों को उखाड़ फेंक दिया, क्योंकि दोनों 'कक्षा' के उपयोग का जिक्र करते हैं, जो मैं खोज रहा था। अंत में, मैंने मैट का जवाब चुना क्योंकि यह क्लासफ्रॉमस्ट्रिंग पर 'कक्षा' पर जोर देता है, और संपादन से पहले 'कक्षा' के उपयोग का उल्लेख करने वाला पहला व्यक्ति था। –

+0

@Ned Batchelder: टैग बदलने के लिए धन्यवाद। कुछ कारणों से, 'objectivec' टैग के ड्रॉप-डाउन सूची में 'ऑब्जेक्ट-सी' की तुलना में कई और आइटम (लगभग 200) दिखाता है जो तब दिखाई देता है जब मैंने प्रश्न में टैग जोड़े, लेकिन अब मैं देखता हूं कि 'objectivec' को रीडायरेक्ट किया गया है 'उद्देश्य-सी' –

+0

@eJames: आपका प्रश्न दिखाता है -सेट क्लास ऑब्जेक्ट नहीं, उदाहरणों पर भेजा जा रहा है, इसलिए मुझे लगता है कि मैट गैलाघर के जवाब में [aClass प्रतिसाद देता है: चयनकर्ता: @ चयनकर्ता (रीसेट)] गलत है। –

उत्तर

22

आप एक वर्ग फ़ंक्शन का उपयोग करने के लिए एक स्ट्रिंग परिवर्तित कर सकते हैं: हालांकि

Class classFromString = NSClassFromString(@"MyClass"); 

NSClassFromString आपके मामले में, आप कक्षा सीधे वस्तुओं का उपयोग कर बेहतर होगा।

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

'कक्षा' प्रकार, और [माई क्लास क्लास] वही है जो मैं ढूंढ रहा था। धन्यवाद! –

+0

माइकल त्सई ने इंगित किया है कि [एक्लास जवाब देने के लिए चयनकर्ता: @ चयनकर्ता (रीसेट)] लाइन को इसके बजाय [एक्लास इंस्टेंस रीस्पॉन्डटॉ चयनकर्ता: @ चयनकर्ता (रीसेट)] पढ़ना चाहिए। मैं अपने प्रश्न में बदलाव कर रहा हूं, आप अपने उत्तर में ऐसा ही कर सकते हैं। –

2

ऐसा लगता है कि आप की तरह कुछ चाहता हूँ लगता है। या आप बस [[klass alloc] init] का उपयोग कर सकते हैं।

यह कॉल करने के लिए:

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

आपको बस इतना करना है, यह बेहतर हो सकता है की कोशिश कर रहे हैं क्या पर निर्भर करता है तार से वर्ग ऑब्जेक्ट, जैसे आसपास पारित करने के लिए:

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

आपके उत्तर के लिए धन्यवाद। मैं आपके संपादन में वर्णित [MyClass क्लास] दृष्टिकोण का उपयोग करूंगा। –

+0

जब तक आप उद्देश्य-सी ++ के लिए संकलित नहीं होते हैं, तो आप चर "वर्ग" नाम दे सकते हैं। – cncool

3

यह बहुत आसान है गतिशील रूप से एक वर्ग निर्दिष्ट करें, वास्तव में आप इसे इसके नाम से संदर्भित कर सकते हैं:

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

एक अन्य युक्ति, मैं एक नामकरण 'प्रबंधित ऑब्जेक्ट' का उपयोग करके शून्य, क्योंकि अधिकांश कोको प्रोग्रामर कोर डेटा से एनएसएमएनेज ऑब्जेक्ट के रूप में पढ़ेंगे। विभिन्न प्रकार की वस्तुओं के संग्रह के प्रबंधन के बजाय आपको वैश्विक एनएसएनोटिफिकेशन (जो आपकी सभी रीसेट-सक्षम ऑब्जेक्ट्स सब्सक्राइब किया जाता है) का उपयोग करना आसान हो सकता है, लेकिन आप मुझसे जितना निर्णय लेते हैं, उससे अधिक जानकारी प्राप्त कर सकते हैं।

+0

NSManagedObject के बारे में अच्छी बात। संभावित भ्रम से बचने के लिए मैं अपना प्रश्न बदलूंगा। –

3

जवाब अन्य उत्तर से लापता का सा है कि आप एक @protocol अपने +createInstance और +reset तरीकों से युक्त निर्धारित कर सकते है।

+0

टिप के लिए धन्यवाद! मैं प्रोटोकॉल का उपयोग करने की योजना बना रहा हूं, लेकिन मुझे इस सवाल में इसका जिक्र करने की आवश्यकता महसूस नहीं हुई। –

संबंधित मुद्दे

 संबंधित मुद्दे