2009-11-13 14 views
10

मेरे पास दो कार्य हैं जिनका उपयोग मुझे करना चाहिए? कृपया अंतर बताएं।NSMutableArray -init बनाम + arrayWithCapacity:

एक:

- (NSMutableArray *)FunctionA:(int)count { 

    NSMutableArray *a = [[NSMutableArray alloc] init]; 

for (int i = 0; i < count; i++) { 
    [a addObject:[NSNumber numberWithInt:0] ]; 
    } 

    return [a autorelease]; 
} 

बी:

-(NSMutableArray *)FunctionB:(int)count { 

NSMutableArray *b = [NSMutableArray arrayWithCapacity:count]; 

for (int i=0;i<count; i++){ 
    [b addObject:[NSNumber numberWithInt:0] ]; 
} 

return b; // or [b autorelease] ? 
} 

उत्तर

28

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

दूसरे ने सरणी को एक संकेत दिया है (आपको शायद "इस" कमरे "की आवश्यकता होगी) ताकि ज्ञात संख्याओं को जोड़ते समय सरणी को बढ़ाने के ऊपरी हिस्से से बचें। बेशक यदि आवश्यक हो तो यह अभी भी बड़ा हो जाएगा (जैसे कि आपने क्षमता निर्दिष्ट नहीं की है)। यदि आप पहले से ही समय से पहले गिनती जानते हैं तो आपको इस दृष्टिकोण का उपयोग करना चाहिए। यह एक बड़ी गिनती के साथ तेजी से है।

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

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

[[NSMutableArray alloc] initWithCapacity:capacity];

... फिर जब तैयार उसे छोड़ दें। यह आपको ऑटोरेलीज पूल का उपयोग करने से स्मृति उपयोग पर अधिक नियंत्रण देता है, जो आईफोन प्लेटफार्म पर एक महत्वपूर्ण विचार है।

याद रखें, हालांकि: पहले मापें, फिर आवश्यक होने पर अनुकूलित करें।

1

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

यह आमतौर पर इतना तेज़ है कि आप भी ध्यान नहीं देंगे लेकिन यह इसे धीमा कर सकता है। आकार के साथ म्यूटेबल सरणी बनाना प्रारंभिक रूप से निर्दिष्ट आकार की सरणी बनाता है ताकि उम्मीद है कि कम आकार बदलना होगा।

1

पहले उदाहरण में, आपको सरणी की स्मृति का प्रबंधन करना होगा, क्योंकि आप इसे +alloc और -init का उपयोग करके बनाते हैं (यही कारण है कि आपको -autorelease इसे भेजने की आवश्यकता है)।

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

यदि आप एक ऑटोरेलेज्ड सरणी वापस करना चाहते हैं, तो दूसरा विकल्प शायद अधिक बेहतर होगा, क्योंकि +arrayWithCapacity: पहले से ही ऑटोरेलेज्ड सरणी वापस कर देगा। इसके अलावा, आपके द्वारा वापस लौटाए गए सरणी पहले से ही ऑटोरेलेज्ड है, इसलिए आपको -autorelease स्वयं को भेजने की आवश्यकता नहीं है।

यदि आपके पास स्मृति प्रबंधन के साथ कोई और चिंता है, तो Apple Memory Management Guidelines पढ़ना आवश्यक है।

0

मैं बी का उपयोग करेंगे:

प्लस के साथ मैं यह

  • सरणी के रूप में यह आप के लिए बड़ा
  • arrayWithCapacity: autoreleases बढ़ता आकार बदलने के लिए तो तुम नहीं की जरूरत नहीं होगी रहे हैं है, यह कोड पठनीयता में सुधार करता है imho

मुझे उम्मीद है कि इससे मदद मिलती है।

+0

हालाँकि ऐसी परिस्थितियों में जहां आप अधिक नियंत्रण चाहते हैं (आप कितनी मेमोरी का उपयोग कर रहे हैं) पर, आप इसे अभी भी [[एनएसएमयूटेबलएरे ऐलोक] initWithCapacity: c] के साथ बना सकते हैं, फिर जब आप तैयार हों तो इसे छोड़ दें। –

+0

बस मेरी पिछली टिप्पणी को स्पष्ट करने के लिए - यह आईफोन पर एक महत्वपूर्ण विचार है, जिसका उल्लेख मैंने "आईफोन" टैग के कारण किया है। :-) –

+0

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

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