2009-03-23 6 views
6

मुझे लगता है कि स्मृति चेतावनी हो रही है और इसलिए मैं, लीक को खोजने के लिए, स्मृति, आदि के अधिक कुशल उपयोग करने के कोशिश कर रहा हूँ उपकरण की मदद से एक iPhone अनुप्रयोग है। अन्य चीजों के अलावा, मैं किसी भी ऑटोरेलेज्ड ऑब्जेक्ट्स को लेने और मैन्युअल एलोक/इनिट/रिलीज ऑब्जेक्ट्स के साथ प्रतिस्थापित करने की कोशिश कर रहा हूं। हालांकि, कुछ एपीआई कॉल में 'init' संस्करण नहीं दिखता है (नीचे कोड देखें)।इंस्ट्रूमेंट्स लीक और ऑब्जेक्ट ऑलोक का उपयोग करना: क्या ऑटोरेलेज्ड ऑब्जेक्ट्स लीक के रूप में गिना जाता है?

  1. अगर मैं एपीआई 'में फोन' और वापस अनिवार्य रूप से autoreleased वस्तुओं मिलता है, इन वस्तुओं उपकरण में लीक के रूप में दिखाई कर सकते हैं: मैं बेशक कुछ बुनियादी गलतफहमी है? ऐसा लगता है कि मैं इस व्यवहार को इंस्ट्रूमेंट्स में देखता हूं।

  2. यदि हाँ 2 करने के लिए, मैं सिर्फ कोई 'गैर autorelease' वैकल्पिक हो, तो अनदेखा कर देना चाहिए और मैं एक एपीआई कि मैं जरूरत उपयोग कर रहा हूँ? इसके अलावा, अगर इस कोड को बहुत कुछ कहा जाता है, तो क्या मुझे पूरी तरह से एल्गोर पर पुनर्विचार करना चाहिए?

यहां मेरे एप्लिकेशन से कुछ उपयोगिता कोड है जिसे बहुत कुछ कहा जाता है। मूल रूप से निर्धारित करता है कि क्या दो तिथियां अर्थपूर्ण रूप से 'बराबर' हैं। और रिहाई इस स्मृति लीक को कम जब बाद में उपकरण में भाग गया के रूप में मैं मैन्युअल NSDate बनाने के लिए शुरू कर दिया था (- मैं बाहर टिप्पणी की कोड में छोड़ दिया है ताकि आप सुधार के प्रकार देख सकते हैं मैं अपने codebase में के बाद जा रहा हूँ) जिसने मदद की। हालांकि, मैं अब भी तारीख घटक जिन वस्तुओं पर मेरा मानना ​​है कि लीक कर रहे हैं ... लेकिन यह एक API कॉल है (कोड स्वरूपण के लिए खेद है, लेकिन मैं इतना इस पर सुधार करने के लिए नहीं कर पा रहे):

+ (BOOL)isDayEqualToDay:(NSDate*)date anotherDate:(NSDate*)anotherDate 
{ 

    NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    //NSCalendar *cal; 
    NSDateComponents *componentsFromDate, *componentsFromAnotherDate; 
    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;  
    //cal = [NSCalendar currentCalendar]; 
    componentsFromDate = [cal components:unitFlags fromDate:date]; 
    componentsFromAnotherDate = [cal components:unitFlags fromDate:anotherDate]; 

    BOOL bDatesEqual = ([componentsFromDate year] == [componentsFromAnotherDate year] && 
         [componentsFromDate month] == [componentsFromAnotherDate month] && 
         [componentsFromDate day] == [componentsFromAnotherDate day]); 

    [cal release]; 

    return bDatesEqual; 

    /* 
    return (
     [componentsFromDate year] == [componentsFromAnotherDate year] && 
     [componentsFromDate month] == [componentsFromAnotherDate month] && 
     [componentsFromDate day] == [componentsFromAnotherDate day] 
    );*/ 
} 

मुझे लगता है कि घटक FromDate और घटकFromAnotherDate लीक के रूप में दिखाई दे रहे हैं लेकिन वहां केवल वस्तुएं एनएसडीएटी एपीआई कॉल (ऑटोरेलेज्ड) से लौट आईं। यह सुनिश्चित नहीं है कि मैं इसे और अधिक कुशल बनाने के लिए वास्तव में और क्या कर सकता हूं और मैं अपनी समझ पर सवाल उठा रहा हूं कि उपकरण का सर्वोत्तम उपयोग कैसे करें। सुझाव?

उत्तर

4

Autoreleased वस्तु मेमोरी लीक के रूप में नहीं दिखाना चाहिए। हालांकि, कभी-कभी एपीआई में उनके अंदर मेमोरी लीक होती है। आपको सेब के साथ एक बग रिपोर्ट दर्ज करनी चाहिए। एनएससीएंडर और एनएसडीएट कॉम्पोननेट जैसी नई कक्षाएं विशेष रूप से संदिग्ध हैं।

autorelease बनाम बनाए रखने के लिए के रूप में, सामान्य नियम है कि यह कोई फर्क नहीं पड़ता जब तक आप एक तंग पाश में हो रहा है। उस स्थिति में, यदि तंग लूप घटना छोड़ने के बिना हजारों बार जा रहा है, तो इसका मतलब है कि आप ऑटोरेलीज पूल को "साफ" नहीं करते हैं।

3

जब GCD की तरह सामान का उपयोग कर वहाँ एक autorelease पूल है, लेकिन आप जानते हुए भी जब (यदि कभी) डिफ़ॉल्ट autorelease पूल बहा दिया जाता है का कोई रास्ता नहीं है। यदि आप आश्वस्त हैं कि एटोरलेज्ड ऑब्जेक्ट्स रिलीज़ नहीं हो रहे हैं, तो सुनिश्चित करें कि आप थ्रेडिंग एपीआई का उपयोग कर रहे हैं जिसे आप उपयोग कर रहे हैं। अगर स्मृति मुझे सही सेवा प्रदान करती है तो जीसीडी कॉल (dispatch_async) आपके लिए ऑटोरेलीज पूल टाइप करता है, लेकिन पूल की वास्तविक निकासी में काफी समय लग सकता है। दूसरी तरफ NSOperations आपको ऑटोरेलीज पूलिंग के मालिक होने देते हैं।

मैंने 10 सेकंड अंतराल पर निर्भर उपकरणों में मेमोरी रिसाव का पता लगाया है जिसके परिणामस्वरूप एक ऑटो रिलीज पूल निकालने से पहले लंबे समय तक देरी के कारण झूठी मेम लीक चेतावनियां हुईं। तो अपमानजनक कोड को लपेटने का प्रयास करें:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
... [your code] ... 
[pool drain]; 

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

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

+0

जीडीसी डीबग करने के लिए इंस्ट्रुमेंट्स का उपयोग करने का कोई तरीका नहीं लगता है। क्या कोई और तरीका है? –

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