मैं NSMutableArray को NSArray में कैसे परिवर्तित करूं उद्देश्य सी?
NSArray *array = mutableArray;
मैं NSMutableArray को NSArray में कैसे परिवर्तित करूं उद्देश्य सी?
NSArray *array = mutableArray;
जवाबों:
NSArray *array = [mutableArray copy];
Copyअपरिवर्तनीय प्रतियां बनाता है। यह काफी उपयोगी है क्योंकि Apple विभिन्न अनुकूलन कर सकता है। उदाहरण के लिए copyएक अपरिवर्तनीय सरणी पर भेजने से केवल ऑब्जेक्ट और रिटर्न ही बरकरार रहता है self।
यदि आप कचरा संग्रहण या एआरसी का उपयोग नहीं करते हैं तो याद रखें कि -copyवह वस्तु बरकरार रखती है।
copyएक सामान्य NSArray बनाता है और NSMutableArray नहीं?
NSArrayऔर NSMutableArray, NSStringऔर NSMutableString। लेकिन उदाहरण के लिए नहीं NSViewControllerजिसमें हमेशा परिवर्तनशील स्थिति होती है।
एक NSMutableArrayउपवर्ग है, NSArrayइसलिए आपको हमेशा बदलने की आवश्यकता नहीं होगी, लेकिन यदि आप यह सुनिश्चित करना चाहते हैं कि सरणी को संशोधित नहीं किया जा सकता है तो आप NSArrayइन तरीकों में से किसी एक को बना सकते हैं, इस पर निर्भर करता है कि आप इसे ऑटोरेल्ड चाहते हैं या नहीं:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
संपादित करें: जोर्ज स्कोली द्वारा प्रदान किया गया समाधान यह करने का एक बेहतर तरीका है और बहुत अधिक क्लीनर है, खासकर अब जब हमारे पास एआरसी है और यहां तक कि ऑटोरेलिज को भी कॉल करने की आवश्यकता नहीं है।
मुझे 2 मुख्य समाधान पसंद हैं:
NSArray *array = [NSArray arrayWithArray:mutableArray];
या
NSArray *array = [mutableArray copy];
प्राथमिक अंतर मैं उन्हें देख उनका व्यवहार जब mutableArray नहीं के बराबर है है :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]इसे सरल बनाया जा सकता है [nil copy]। वस्तुनिष्ठ-ग में शून्य पर भेजा गया कोई भी संदेश हमेशा शून्य होगा। "कुछ भी नहीं" और "इसमें कुछ नहीं के साथ एक सरणी" के बीच अंतर को याद रखना महत्वपूर्ण है।
आप इस कोड की कोशिश करो ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
तथा
NSArray *myArray = [myMutableArray copy];
नीचे NSMutableArray को NSArray में बदलने का तरीका है:
//oldArray is having NSMutableArray data-type.
//Using Init with Array method.
NSArray *newArray1 = [[NSArray alloc]initWithArray:oldArray];
//Make copy of array
NSArray *newArray2 = [oldArray copy];
//Make mutablecopy of array
NSArray *newArray3 = [oldArray mutableCopy];
//Directly stored NSMutableArray to NSArray.
NSArray *newArray4 = oldArray;
स्विफ्ट 3.0 में नया डेटा टाइप एरे है । letकीवर्ड का उपयोग करके ऐरे को घोषित करें तो वह NSArray बन जाएगा और यदि varकीवर्ड का उपयोग करने की घोषणा करता है तो यह NSMutableArray बन जाएगा ।
नमूना कोड:
let newArray = oldArray as Array
ArrayNSArrayNSMutableArray
उद्देश्य-सी में:
NSArray *myArray = [myMutableArray copy];
स्विफ्ट में:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
इस [mutableArray copy] एंटीपैटर्न सभी नमूना कोड से अधिक है। फेंकने योग्य उत्परिवर्ती सरणियों के लिए ऐसा करना बंद करें जो क्षणिक हैं और वर्तमान दायरे के अंत में निपटाए जाते हैं।
ऐसा कोई तरीका नहीं है कि रनटाइम एक उत्परिवर्तित सारणी की व्यर्थ नकल को अनुकूलित कर सके जो कि केवल दायरे से बाहर जाने के बारे में है, 0 से घटाया गया और अच्छे के लिए डील किया गया।
NSMutableArrayएक NSArrayचर को असाइन करने से इसे कवर नहीं किया जाएगा (जो कि ओपी का सवाल है)। इस तरह के मूल्य को उजागर करना (उदाहरण के लिए रिटर्न वैल्यू या संपत्ति के रूप में) के परिणामस्वरूप बहुत मुश्किल से मुद्दों को डिबग किया जा सकता है अगर उस मूल्य को अप्रत्याशित रूप से उत्परिवर्तित किया गया था। यह दोनों आंतरिक और बाह्य उत्परिवर्तन पर लागू होता है क्योंकि उत्परिवर्तनीय मूल्य साझा किया जाता है।
NSMutableArrayवैरिएबल में असाइन करना पर्याप्त है। चूँकि ऑब्जेक्ट कभी भी एक उत्परिवर्ती सारणी नहीं होता है, इसलिए उस पर उत्परिवर्तन विधियों को कॉल करना सफल होगा और साझा किए गए डेटा को म्यूट करेगा। यदि दूसरी ओर मूल परिवर्तनशील सरणी की प्रतिलिपि बनाई गई थी - इसे एक अपरिवर्तनीय सरणी में बदलना - और फिर एक NSMutableArrayचर के लिए असाइन किया गया था और उस पर कॉल करने के तरीकों को बदलना था, तो वे कॉल doesNotRespondToSelectorत्रुटियों के साथ विफल हो जाएंगे क्योंकि ऑब्जेक्ट जो उत्परिवर्तन विधि कॉल प्राप्त करता है, वह है वास्तव में अपरिवर्तनीय और उन तरीकों का जवाब नहीं है।
यदि आप परिवर्तनशीलता के माध्यम से एक सरणी का निर्माण कर रहे हैं और फिर एक अपरिवर्तनीय संस्करण वापस करना चाहते हैं, तो आप विरासत के माध्यम से बस "सरणी" के रूप में उत्परिवर्तित सरणी को वापस कर सकते हैं।
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
यदि आप एक अपरिवर्तनीय NSArray के रूप में (तकनीकी रूप से अभी भी परिवर्तनशील) रिटर्न ऑब्जेक्ट का इलाज करने के लिए कॉल करने वाले पर "भरोसा" करते हैं, तो यह इससे सस्ता विकल्प है [mutableArray copy]।
यह निर्धारित करने के लिए कि क्या यह एक प्राप्त वस्तु को बदल सकता है, संदेश के रिसीवर को वापसी मूल्य के औपचारिक प्रकार पर भरोसा करना चाहिए। यदि यह प्राप्त करता है, उदाहरण के लिए, एक सरणी वस्तु अपरिवर्तनीय के रूप में टाइप की जाती है, तो उसे इसे म्यूट करने का प्रयास नहीं करना चाहिए । यह निर्धारित करने के लिए एक स्वीकार्य प्रोग्रामिंग अभ्यास नहीं है कि क्या कोई वस्तु अपनी कक्षा की सदस्यता के आधार पर उत्परिवर्तित है।
उपरोक्त अभ्यास पर यहां और अधिक विस्तार से चर्चा की गई है:
सर्वोत्तम प्रैक्टिस: यदि रिटर्न टाइप NSArray है, तो mutableArray.copy या mutableArray लौटें
मैं स्विफ्ट 3 में उत्तर की खोज कर रहा था और इस प्रश्न को खोज में पहली बार परिणाम के रूप में दिखाया गया था और मुझे इससे उत्तर की प्रेरणा मिली, इसलिए यहां स्विफ्ट 3 कोड है
let array: [String] = nsMutableArrayObject.copy() as! [String]
NSArray *array = [mutableArray copy];