2010-10-12 13 views
7

मैं के समान कार्य की एक संख्या है निम्नलिखित:कोई म्यूटेबल ऑब्जेक्ट वापस नहीं करने का कोई कारण है जहां किसी की अपेक्षा नहीं की जाती है?

+ (NSArray *)arrayOfSomething 
{ 
    NSMutableArray *array = [NSMutableArray array]; 

    // Add objects to the array 

    return [[array copy] autorelease]; 
}

मेरा प्रश्न इस विधि की अंतिम पंक्ति के बारे में है: यह बेहतर परिवर्तनशील वस्तु लौट रहा है और एक प्रति कार्रवाई से बचने के लिए, या अपरिवर्तनीय वापस जाने के लिए नकल? क्या एक म्यूटेबल ऑब्जेक्ट लौटने से बचने के लिए कोई अच्छा कारण है जहां किसी की अपेक्षा नहीं की जाती है?

(मुझे पता है कि यह एक NSMutableArray वापस जाने के लिए कानूनी है, क्योंकि यह NSArray का एक उपवर्ग है मेरा प्रश्न है या नहीं, यह एक अच्छा विचार है।।)

+0

बेशक, आपके द्वारा दिया गया उदाहरण केवल पहली जगह में प्रतिलिपि बनाये बिना मूल को वापस कर सकता है। साथ ही, यह देखते हुए कि यह एक क्लास विधि है (और एक फ़ंक्शन नहीं, वैसे भी), क्या आपको वास्तव में हर बार सरणी का एक नया उदाहरण बनाने की आवश्यकता है? यदि आप प्रतिलिपि को कैश करते हैं, तो बिंदु काफी मज़ेदार होगा। – jlehr

+0

+1 क्योंकि मैंने कुछ सचमुच महत्वपूर्ण सीखा है कि सभी उद्देश्य-सी प्रोग्रामर को जवाब खोजते समय पता होना चाहिए। – JeremyP

उत्तर

4

यह एक जटिल विषय है। मुझे लगता है कि आपको object mutability पर ऐप्पल के दिशानिर्देशों का संदर्भ देना सबसे अच्छा है।

निर्धारित करने के लिए यह एक प्राप्त वस्तु को बदल सकते हैं कि क्या, रिसीवर वापसी की औपचारिक प्रकार पर भरोसा करना चाहिए:

एप्पल इस आत्मनिरीक्षण का उपयोग कर के विषय पर कहने के लिए एक लौटे वस्तु की अस्थिरता का निर्धारण करने के लिए किया मूल्य। यदि यह प्राप्त करता है, उदाहरण के लिए, एक सरणी वस्तु अपरिवर्तनीय के रूप में टाइप की गई है, तो इसे इसे बदलने का प्रयास नहीं करना चाहिए। यह अगर एक वस्तु अपने वर्ग सदस्यता के आधार पर परिवर्तनशील है निर्धारित करने के लिए एक स्वीकार्य प्रोग्रामिंग प्रथा नहीं है

(मेरा जोर)

लेख कई बहुत अच्छे कारणों से आप पर आत्मनिरीक्षण उपयोग नहीं करना चाहिए देने के लिए पर चला जाता है एक लौटा ऑब्जेक्ट यह निर्धारित करने के लिए कि क्या आप इसे बदल सकते हैं उदाहरण के लिए

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

और

आप अपने subviews (subviews विधि) के लिए NSView पूछने के लिए और यह एक वस्तु है कि एक NSArray घोषित किया जाता है, लेकिन जो एक NSMutableArray आंतरिक रूप से हो सकता है देता है।फिर आप उस सरणी को किसी अन्य कोड पर पास करते हैं, जो आत्मनिरीक्षण के माध्यम से इसे संशोधित करने और इसे बदलने के लिए निर्धारित करता है। इस सरणी को बदलकर, कोड एनएसवीव के आंतरिक डेटा संरचनाओं को बदल रहा है।

उपर्युक्त को देखते हुए, यह आपके उदाहरण में उत्परिवर्तनीय सरणी वापस करने के लिए पूरी तरह से स्वीकार्य है (बशर्ते, आप इसे वापस करने के बाद इसे कभी भी उत्परिवर्तित न करें, क्योंकि तब आप अनुबंध तोड़ देंगे)।

कहा जाता है कि, लगभग किसी ने कोको ऑब्जेक्ट्स गाइड के उस हिस्से को पढ़ा नहीं है, इसलिए रक्षात्मक प्रोग्रामिंग आपको एक अपरिवर्तनीय प्रतिलिपि बनाने के लिए बुलाएगी और तब तक लौट आएगी जब तक कि प्रदर्शन प्रोफाइलिंग से पता चलता है कि ऐसा करने में कोई समस्या नहीं है।

+1

मैन, मैंने उस दस्तावेज़ को कई बार संदर्भित किया है और किसी भी तरह से हमेशा उस खंड से चिपकाया है। मैं वास्तव में ऐसे प्रोग्रामर हूं जिसकी आप रक्षा करना चाहते हैं। (मेरे "रक्षा" में, मैंने वास्तव में किसी ऑब्जेक्ट की उत्परिवर्तन का परीक्षण नहीं किया है।) –

+1

@ रोबोट के: क्लब में शामिल हों। कुबी के जवाब से जुड़ी आपको मेरी पहली टिप्पणी के रूप में, अगर मैंने इस प्रश्न के लिए विषय का शोध करने का फैसला नहीं किया है, तो मैंने वापस लौटे अपरिवर्तनीय वस्तुओं पर आत्मनिरीक्षण का उपयोग करने की वैधता पर सवाल नहीं उठाया होगा। हालांकि आप की तरह, मैंने कभी ऐसा कुछ भी नहीं किया है। – JeremyP

+0

NSObject isKindOfClass के लिए प्रलेखन देखें: समान चेतावनी के लिए विधि: http://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/OCC/intfm/NSObject/isKindOfClass: – titaniumdecoy

3

लघु उत्तर: यह

मत करो

लंबा उत्तर: यह निर्भर करता है। यदि किसी ऐसे व्यक्ति द्वारा उपयोग किए जाने पर सरणी बदल रही है जो अपेक्षाकृत स्थिर है, तो आप कुछ परेशान त्रुटियों का कारण बन सकते हैं जो ट्रैक करने के लिए दर्द होंगे। आपके द्वारा की गई प्रतिलिपि/ऑटोरेलीज़ करना बेहतर होगा और केवल उस समय के वापसी प्रकार पर फिर से जाएं और अगर यह पता चला कि एक महत्वपूर्ण प्रदर्शन हिट है तो यह वापस आ जाएगा।


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

+0

क्या आप वास्तविक जीवन के मामले का नाम दे सकते हैं जहां कुछ अजीब होगा? मेरे दिमाग में यह अनजान सरणी के साथ गड़बड़ करना बहुत कठिन होगा - क्योंकि आपको संकलक से प्रत्येक "सामान्य" विधि कॉल के लिए चेतावनी मिल जाएगी। निश्चित रूप से प्रदर्शनकर्ता और दोस्तों का प्रदर्शन है, लेकिन इसके अलावा ..? –

+1

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

+0

इसके अलावा, कुछ वर्ग (विशेष रूप से ढांचे वर्ग) यह देखने के लिए जांच करते हैं कि क्या वे एक म्यूटेबल सरणी पारित कर चुके हैं और फिर इसे कॉपी करें। एक अपरिवर्तनीय सरणी लौटने से उस चरण को छोड़ दिया जाएगा। –

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

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