2012-01-22 10 views
6

यहाँ मेरी कोशिश हैमैं एनएसएआरएआरई कैसे बढ़ा सकता हूं?</p> <p>एच फ़ाइल:

@interface Strings : NSArray 
@end 

एम फ़ाइल:

@implementation Strings 
- (id) init 
{ 
    [self initWithObjects: 
    @"One.", 
    nil]; 
    return self; 
} 
@end 

जब मैं चलाने मैं इस मिल:

'NSInvalidArgumentException', कारण: '* - [एनएसएआरएआर इनिट विथ ऑब्जेक्ट्स: गिनती:]: विधि केवल सार वर्ग के लिए परिभाषित की गई है। परिभाषित करें - [स्ट्रिंग्स initWithObjects: गिनती:]! '

यह है कि मैं क्या बजाय किया है:

एच फ़ाइल:

@interface Strings : NSObject 
+ (NSArray*) getStrings; 
@end 

एम फ़ाइल:

@implementation Strings 
+ (NSArray*) getStrings 
{ 
    NSArray* strings = [[NSArray alloc] initWithObjects: 
    @"One.", 
    nil]; 
    return strings; 
} 
@end 

उत्तर

8

NSArrayclass cluster (link to Apple's documentation) है। इसका अर्थ यह है कि जब आप NSArray बनाने का प्रयास करते हैं, तो सिस्टम NSArray के कुछ निजी उप-वर्ग बनाता है। NSArray कक्षा सिर्फ एक इंटरफ़ेस परिभाषित करता है; NSArray के उप-वर्ग इंटरफ़ेस के कार्यान्वयन प्रदान करते हैं।

आप NSArray का अपना उप-वर्ग लिख सकते हैं, लेकिन आपको सरणी में ऑब्जेक्ट्स के लिए अपना स्वयं का संग्रहण प्रदान करना होगा। आपको उस भंडारण को स्वयं शुरू करना होगा। त्रुटि संदेश यह कहकर आपको बता रहा है कि आपको अपने उप-वर्ग में initWithObjects:count: ओवरराइड करना होगा। आपके ओवरराइड को ऑब्जेक्ट्स को आपके क्लास कार्यान्वयन के हिस्से के रूप में आवंटित किए जाने वाले संग्रहण में रखना होगा।

variadic initWithObjects: विधि के NSArray कार्यान्वयन सिर्फ initWithObjects:count: के चारों ओर एक आवरण है, तो आप initWithObjects: लागू करने के लिए नहीं है।

+1

साथ ही, सुनिश्चित करें कि आप * [एनएसएआरएआरई क्लास रेफरेंस] (http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/) के "सबक्लासिंग नोट्स" अनुभाग को पढ़ और ** समझते हैं। कक्षाएं/NSArray_Class/NSArray.html # // apple_ref/doc/uid/20000137-740795) * अपने स्वयं के 'एनएसएआरएआरई' सबक्लास लिखने से पहले। –

2

NSArray इस तरह से किया जा रहा subclassed समर्थन नहीं करता। हालांकि, आप एक श्रेणी जोड़ सकते हैं, हालांकि यह सार्वभौमिक रूप से अनुशंसित नहीं है।

अधिक विचारों के लिए Objective C - Subclassing NSArray देखें।

+0

मैं स्वयं = [स्वयं initWithObjects: में बदल गया लेकिन इससे मदद नहीं मिली। –

+0

मुझे लगता है कि यह हो सकता है कि [एनएसएआरएआरए आवंटन] वास्तव में एक एनएसएआरएआरई आवंटित नहीं करता है, इसलिए जब मैं करता हूं, तो कोई कार्यान्वयन नहीं होता है। मदद! लेकिन यह initWithObjects के बारे में क्यों जाता है: गिनती:? –

+0

आपको क्यों लगता है कि आपको एनएसएआरएआरई को उप-वर्ग करने की आवश्यकता है? जब तक आप एक विशेष बैकिंग स्टोर नहीं बना रहे हैं, यह आमतौर पर एक अच्छा दृष्टिकोण नहीं है। – StilesCrisis

1

शायद

self = [super initWithObjects:...]; 
+0

यह सच है, लेकिन विशिष्ट में एनएसएआरएआरई को उप-वर्गीकरण में विशेष नियम भी हैं। – StilesCrisis

+0

सच है। खैर, मैं फिर भी जवाब छोड़ दूंगा। पहली चीजें पहले। –

+0

@StilesCrisis, और आप मेरा अपवित्र प्राप्त करते हैं :) –

1

आप स्वयं असाइन करने और अपनी सुपर क्लास 'init विधि कॉल करने की जरूरत है।

if (self = [super initWithObjects:...]) { 
    ... 
} 

return self; 
+0

यह सच है, लेकिन विशेष रूप से एनएसएआरएआरई को उप-वर्गीकरण में विशेष नियम भी हैं। – StilesCrisis

5

NSArray से प्राप्त करना कुछ ऐसा है जो आपको टालना चाहिए। प्रलेखन से:

याद रखें कि एनएसएआरएआरई कक्षा क्लस्टर के लिए सार्वजनिक इंटरफ़ेस है और यह आपके उप-वर्ग के लिए क्या है। एनएसएआरएआरई के आदिम तरीकों में किसी भी नामित प्रारंभकर्ता शामिल नहीं हैं। इसका मतलब है कि आपको अपने उप-वर्ग के लिए भंडारण प्रदान करना होगा और उस भंडारण पर सीधे कार्य करने वाली आदिम विधियों को लागू करना होगा।

इसका मतलब यह है कि जब आप किसी सरणी को प्रारंभ करते हैं, तो आपको NSArray का उदाहरण नहीं मिलता है। आपको एक पूरी तरह से अलग वर्ग का एक उदाहरण मिलेगा जिसमें केवल एक ही इंटरफ़ेस होगा। यही कारण है कि सबक्लासिंग आपके काम के तरीके से काम नहीं करती है: आपको स्वयं को स्टोरेज को पूरी तरह कार्यान्वित करना होगा। यही कारण है कि दस्तावेज आगे बताता है:

एनएसएआरएआरई के किसी भी उप-वर्ग को आदिम उदाहरण विधियों की गिनती और ऑब्जेक्ट ओवरराइड करना चाहिए: इन तरीकों को बैकिंग स्टोर पर काम करना चाहिए जो आप संग्रह के तत्वों के लिए प्रदान करते हैं। इस बैकिंग स्टोर के लिए आप एक स्थिर सरणी, मानक एनएसएआरएआरई ऑब्जेक्ट, या कुछ अन्य डेटा प्रकार या तंत्र का उपयोग कर सकते हैं। आप किसी भी अन्य एनएसएआरएआर विधि के लिए आंशिक रूप से या पूरी तरह से ओवरराइड करना चुन सकते हैं जिसके लिए आप वैकल्पिक कार्यान्वयन प्रदान करना चाहते हैं।

अंतिम लेकिन कम से कम आप को प्रारंभिक रूप से गलत प्रारंभ करना होता।आप super कॉल करने के लिए आवश्यकता होती:

- (id)init 
{ 
    self = [super initWithObjects:@"One", @"Two", nil]; 
    if (!self) return nil; 

    return self; 
} 

लेकिन जैसे-जैसे मैं सिर्फ इतना कहा, यह सिर्फ है कि आसानी से काम नहीं करता। आपको फिर से एक ही अपवाद मिल जाएगा। तो आपको बस NSArray से प्राप्त करने से बचना चाहिए।

क्या आप कर सकते हैं NSArray उदाहरणों में विधियों को जोड़ने के लिए एक श्रेणी जोड़ें।

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