2009-09-22 6 views
7

कहें कि आपके पास एक ऐसी विधि है जो एक नया उत्पन्न एनएसएआरएआरई उदाहरण देता है जो आंतरिक रूप से एनएसएमयूटेबलएरे के साथ बनाया गया है। आप हमेशा कुछ इस तरह करते हैं:उद्देश्य-सी में आपके रिटर्न प्रकारों के साथ आप कितने सावधान हैं?

- (NSArray *)someArray { 
    NSMutableArray *mutableArray = [[NSMutableArray new] autorelease]; 
    // do stuff... 
    return [NSArray arrayWithArray:mutableArray]; // .. or [[mutableArray copy] autorelease] 
} 

या के रूप में है तो आप सिर्फ अस्थायी सरणी वस्तु छोड़ने के लिए और यह सीधे वापसी करते क्योंकि NSMutableArray NSArray का एक उपवर्ग है:

- (NSArray *)someArray { 
    NSMutableArray *mutableArray = [[NSMutableArray new] autorelease]; 
    // do stuff... 
    return mutableArray; 
} 

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

उत्तर

9

मैं return [NSArray arrayWithArray:someMutableArray] करता था, लेकिन मुझे धीरे-धीरे आश्वस्त था कि यह कोई वास्तविक लाभ नहीं देता है। यदि आपके एपीआई का कॉलर घोषित वर्ग के उप-वर्ग के रूप में लौटाए गए ऑब्जेक्ट का इलाज कर रहा है, तो वे इसे गलत कर रहे हैं।

[एनबी:। नीचे bbum की चेतावनी देखें]

+1

मैं आम तौर पर सहमत हूं। हालांकि, यदि लौटाए गए कोड के साथ कॉलिंग कोड की संभावना गंभीर समस्याएं पैदा कर सकती है, तो रक्षात्मक प्रतिलिपि एक अच्छा विचार है। यह फ्रेमवर्क कोड के लिए विशेष रूप से सच है। –

+0

यदि कॉलिंग कोड कुछ एन्क्रिप्ट कर रहा है तो आपके एपीआई का कहना है कि इसे अपरिवर्तनीय माना जाना चाहिए, उन्हें '-मुटेबल कॉपी' करना चाहिए। अन्यथा, यह गलत कर रहा है। ;) (यदि आपको लगता है कि आपको जरूरी है तो कुछ भी आपको रक्षात्मक होने से रोक नहीं रहा है।) – Wevah

+4

वास्तविक समस्या यह है कि यदि आप एक सरणी के लिए एक म्यूटेबल सरणी संदर्भ लौटाते हैं जिसे बाद में उत्परिवर्तित किया जा सकता है, तो कॉलर को एनएसएआरएआरई * प्राप्त हो सकता है मान लें कि सामग्री कभी नहीं बदली ... और ... अच्छा ... * बूम *। – bbum

5

एनएसएमयूटेबलएरे कास्ट एनएसएआरएआरई के रूप में वापस करना बहुत आम है। मुझे लगता है कि ज्यादातर प्रोग्रामर यह महसूस करेंगे कि अगर वे एक अपरिवर्तनीय वस्तु को कम करते हैं और इसे बदल देते हैं, तो वे गंदा कीड़े पेश करने जा रहे हैं।

इसके अलावा

, यदि आप एक NSMutableArray इवर someMutableArray है, और आप एक KVC एक्सेसर विधि में [NSArray arrayWithArray:someMutableArray] लौटने के लिए, यह गंदगी कर सकते हैं KVO। आप "ऑब्जेक्ट्स को अभी भी जुड़े हुए पर्यवेक्षकों के साथ हटा दिया गया था" त्रुटियां प्राप्त करना शुरू कर देंगे।

0

एनएसएआरएआर वास्तव में एक वर्ग क्लस्टर है, एक प्रकार नहीं, वैसे भी। तो कहीं भी आप एक एनएसएआरएआरई देखते हैं, संभावना है कि यह पहले से ही कई अलग-अलग प्रकारों में से एक है। इसलिए 'एनएसएआरएआरए में कनवर्ट करें' कुछ हद तक भ्रामक है; एक एनएसएमयूटेबलएरे पहले से ही एनएसएआरएआरई इंटरफ़ेस के अनुरूप है और यही वह है जो सबसे अधिक होगा।

CocoaObjects fundamentals

किसी भी मामले में, यह देखते हुए कि आप (autorelease करने के लिए और बाद में रखते हुए नहीं, धन्यवाद) एक सरणी लौट रहे हैं तो आप शायद चिंता है कि क्या सरणी परिवर्तनशील है या नहीं की जरूरत नहीं है।

हालांकि, यदि आप सरणी रखते थे, तो आप ग्राहकों को सामग्री को बदलने से रोकने के लिए ऐसा करना चाहेंगे।

+1

वहाँ नहीं एक NSArray प्रोटोकॉल है। एनएसएमयूटेबलएरे एनएसएआरएआरई कक्षा का उप-वर्ग है। –

+0

पीटर, आप बिल्कुल सही हैं, यह मेरे हिस्से - 'इंटरफ़ेस' पर एक गलती थी। मैंने तदनुसार अपना जवाब अपडेट कर लिया है। – AlBlue

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