2009-07-23 9 views

उत्तर

8

दो विधियां अलग-अलग चीजें करती हैं। यदि आपके पास टाइमर है (आपने इसे बनाए रखा है, या इसे आवंटित किया है, या इसकी प्रतिलिपि बनाई है) तो आपको इसे छोड़ना चाहिए। यदि आपने इसे रन लूप पर शेड्यूल किया है, तो आपको इसे रिलीज़ करने के लिए रन लूप के लिए इसे अमान्य कर देना होगा। यदि आपने दोनों चीजें की हैं, तो आपको टाइमर को रिलीज़ और अमान्य करना होगा (हालांकि आमतौर पर टाइमर का मालिक चलाने वाला लूप पर्याप्त होता है)।

+0

पहली रिलीज और फिर रद्द करने में अमान्य? क्या मैं चयनकर्ता में दो तर्कों के साथ तर्क भेज सकता हूं? –

+0

पहले इसे अमान्य करें, फिर इसे जारी करें (यदि आप इसका स्वामी हैं)। कृपया अपना अंतिम प्रश्न स्पष्ट करें। यदि आप पूछ रहे हैं कि क्या आप अमान्य कॉल कर सकते हैं और टाइमर पर केवल एक कॉल के साथ रिलीज कर सकते हैं, तो जवाब नहीं है, जब तक कि आप अपनी खुद की सुविधा विधि नहीं बनाते हैं जो इन दो चीजों को करता है और उस विधि को कॉल करता है। – Felixyz

+0

क्या मैं एनएसटीआईएमईआर में @ चयनकर्ता के साथ अतिरिक्त तर्क भेज सकता हूं? –

0

यह एक टाइमर को हटाने का सही तरीका है जो अभी भी चल रहा है (और आप रुकना चाहते हैं)।

+1

यह मानते हुए कि आप टाइमर के पहले स्थान पर हैं ... यदि आप नहीं करते हैं तो '-release' कॉल क्रैश हो जाएगा। या चाहिए। –

1

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

15

[timer release] केवल टाइमर के "स्वयं" होने पर ही आपको कॉल करने की आवश्यकता है। से Apple's documentation:

क्योंकि रन पाश टाइमर का कहना है, वहाँ आम तौर पर एक बार आप शेड्यूल किया है एक टाइमर के लिए एक संदर्भ रखने की आवश्यकता नहीं है स्मृति प्रबंधन के नजरिए से। चूंकि टाइमर को एक तर्क के रूप में पारित किया जाता है जब आप चयनकर्ता के रूप में अपनी विधि निर्दिष्ट करते हैं, तो आप उस विधि के भीतर उपयुक्त होने पर दोहराने वाले टाइमर को अमान्य कर सकते हैं। हालांकि, कई परिस्थितियों में, आप टाइमर को अमान्य करने का विकल्प भी चाहते हैं-शायद इससे पहले कि यह शुरू हो जाए। इस मामले में, आपको टाइमर का संदर्भ रखने की आवश्यकता है, ताकि जब भी उचित हो, आप इसे एक अमान्य संदेश भेज सकें। यदि आप एक अनुसूचित टाइमर बनाते हैं (“Unscheduled Timers” देखें), तो आपको टाइमर के लिए एक मजबूत संदर्भ बनाए रखना चाहिए (संदर्भ-गणना वाले वातावरण में, आप इसे बनाए रखते हैं) ताकि इसे उपयोग करने से पहले इसे हटाया न जाए।

इसका क्या अर्थ है?

यदि आप alloc और init एक टाइमर, आप चाहिए भी release यह है, तो जैसे:

NSTimer * timer = [[NSTimer alloc] initWith...]; 

NSRunLoop * runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; 
[timer release]; 

... 
... 

[timer invalidate]; 
timer = nil; 

एक बार टाइमर रन पाश में जोड़ दिया गया है, इसके लिए एक संदर्भ अब और रखने के लिए कोई कारण नहीं है , क्योंकि रन लूप का मालिक है। इस मामले में, जैसा कि दिखाया गया है, आप release टाइमर जितनी जल्दी इसे रन लूप में जोड़ते हैं, और फिर जब आप समाप्त कर लेंगे तो बस invalidate होगा। अंतिम पंक्ति (सेटिंग टाइमर nil) सुरक्षा के लिए है। invalidate पर कॉल करने के परिणामस्वरूप टाइमर जारी किया जाएगा (रन लूप द्वारा), इसलिए यह संदर्भ देने के लिए असुरक्षित है जो इसे इंगित करता है। स्थानीय संदर्भ को nil पर सेट करना चीजें कोशेर रखता है।

अगर, हालांकि, आप एक टाइमर इसलिए की तरह सुविधा एक विधि का उपयोग बनाने के लिए:

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...]; 

आप कर बिल्कुल [timer release] फोन करने की जरूरत नहीं! सुविधा विधि टाइमर को रन लूप में जोड़ती है, जो उसके बाद होती है, इसलिए आपको लौटाई गई टाइमर ऑब्जेक्ट पर कोई मेमोरी प्रबंधन करने की आवश्यकता नहीं होती है।आप बस invalidate टाइमर जब आप नहीं रह उपयोग करना चाहते हैं होगा:

[timer invalidate]; 
timer = nil; 

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

+2

जैसे ही आप कॉल करते हैं [टाइमर रिलीज], यह मानना ​​अच्छा नहीं है कि टाइमर अभी भी मान्य है। एक विधि के मामले में, आप ऐसा करने के लिए लगभग हमेशा सुरक्षित होते हैं, लेकिन [टाइमर अमान्य] के बाद [टाइमर रिलीज़] रखा गया था तो कोड बेहतर रूप होगा। –

+0

एक महान व्यावहारिक उत्तर। – Ross