2012-11-23 19 views

उत्तर

27

हाँ, NSTimer (विशेष रूप से टाइमर दोहरा में) target, पैदा कर सकता है जो करने के लिए एक मजबूत संदर्भ बनाए रखेंगे मजबूत संदर्भ चक्र (यानी चक्र को बनाए रखने)। आपके उदाहरण में, हालांकि, टाइमर दोहराया नहीं जाता है, और केवल 0.5 में देरी हो रही है, इसलिए सबसे खराब स्थिति परिदृश्य, आपके पास एक मजबूत संदर्भ चक्र होगा जो स्वचालित रूप से 0.5 सेकंड में स्वयं को हल कर देगा।

लेकिन एक अनसुलझे मजबूत संदर्भ चक्र का एक सामान्य उदाहरण एक NSTimer संपत्ति है कि दोहराता के साथ एक UIViewController के लिए होगा, लेकिन क्योंकि NSTimerUIViewController के लिए एक मजबूत संदर्भ में है, नियंत्रक पास आया खत्म हो जाएगा।

तो, यदि आप NSTimer को एक आवृत्ति चर के रूप में रखते हैं, तो हां, आपको मजबूत संदर्भ चक्र को हल करने के लिए invalidate होना चाहिए। यदि आप केवल scheduledTimerWithTimeInterval पर कॉल कर रहे हैं, लेकिन इसे एक आवृत्ति चर में सहेज नहीं रहे हैं (जैसा कि कोई आपके उदाहरण से अनुमान लगा सकता है), तो NSTimer पूर्ण होने पर आपका मजबूत संदर्भ चक्र हल हो जाएगा।

और, वैसे, आप NSTimers दोहरा के साथ काम कर रहे हैं, NSTimer के मालिक के dealloc में invalidate करने के लिए उन्हें कोशिश मत करो क्योंकि dealloc जब तक मजबूत संदर्भ चक्र हल हो गई है स्पष्ट रूप से कहा जाता है नहीं किया जाएगा। UIViewController के मामले में, उदाहरण के लिए, आप इसे viewDidDisappear में कर सकते हैं।

वैसे, Advanced Memory Management Programming Guide बताता है कि कौन से मजबूत संदर्भ चक्र हैं। जाहिर है, यह एक ऐसे खंड में है जहां वे कमजोर संदर्भों के उचित उपयोग का वर्णन कर रहे हैं, जो यहां लागू नहीं है (क्योंकि इस तथ्य पर आपका कोई नियंत्रण नहीं है कि NSTimer लक्ष्य के मजबूत संदर्भों का उपयोग करता है), लेकिन यह अवधारणाओं को समझाता है मजबूत संदर्भ चक्रों की अच्छी तरह से।


आप अपने NSTimer MacOS 10.12 और iOS 10, में या बाद में self के लिए एक मजबूत संदर्भ रखने के लिए, नहीं करना चाहते हैं, तो आप ब्लॉक गायन उपयोग कर सकते हैं और फिर weakSelf पैटर्न का उपयोग करें:

typeof(self) __weak weakSelf = self; 
[NSTimer scheduledTimerWithTimeInterval:0.5 repeats:false block:^(NSTimer * _Nonnull timer) { 
    [weakSelf showButtons]; 
}]; 

वैसे, मुझे लगता है कि आप showButtons पर कॉल कर रहे हैं। तुम सिर्फ अपने दृश्य पर कुछ नियंत्रण दिखाने की कोशिश कर रहे हैं, तो आप पूरी तरह NSTimer के उपयोग को समाप्त कर सकता है और इस तरह कुछ करना:

self.button1.alpha = 0.0; 
self.button2.alpha = 0.0; 

[UIView animateWithDuration:0.25 
         delay:0.5 
        options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction 
       animations:^{ 
        self.button1.alpha = 1.0; 
        self.button2.alpha = 1.0; 
       } 
       completion:nil]; 

यह NSTimer वस्तुओं के मुद्दों को बनाए रखने के कष्ट नहीं होता है, और दोनों करता है विलंब के साथ-साथ बटनों की सुंदर दिखावट सभी एक बयान में।यदि आप अपने showButtons विधि में अतिरिक्त प्रोसेसिंग कर रहे हैं, तो आप इसे completion ब्लॉक में डाल सकते हैं।

+0

ग्रेट उत्तर, लेकिन शायद मैंने इस तथ्य को स्पष्ट नहीं किया है कि मैं वास्तव में एनएसटीमर * टाइमर के साथ .h फ़ाइल में इसे अस्वीकार नहीं करता हूं, मैं बस उस कोड को .m फ़ाइल में जोड़ता हूं, इसलिए मैं इसे अमान्य या शून्य नहीं कर सकता । इस मामले में यह अभी भी ठीक है अगर मैं अपने टाइमर का उपयोग करता हूं, या आपके द्वारा प्रदान किए गए कोड का उपयोग करना बेहतर है? – Alessandro

+0

@Alessandro मैंने वास्तव में माना कि आपने टाइमर के लिए एक ivar बनाए रखा नहीं है। लेकिन, जाहिर है, अगर आप 'व्यूविल डिस्प्लेयर' में 'अमान्य' करना चाहते हैं, तो आपको ऐसा करना होगा। (एक तरफ के रूप में, आपको निजी ivars को अपने एचएच में रखना नहीं है। निजी वर्ग विस्तार बेहतर है।) और कुछ बार आपने 'NSTimer' को' nil' सेट करने के बारे में उल्लेख किया है। कृपया ध्यान दें कि यह मजबूत संदर्भ चक्र को हल नहीं करता है। टाइमर को या तो पूरा करने की आवश्यकता है (और दोहराया नहीं जा रहा है) या आपको 'अमान्य' करने की आवश्यकता है (अपने नए इवर का उपयोग करके)। – Rob

1

आप एक संपत्ति में सहेजने रहे हैं का उपयोग कर रहा है, तो हाँ, आप नहीं के बराबर करने के लिए इसे स्थापित करने के लिए बाद यह चयनकर्ता निकाल दिया की क्या ज़रूरत है।

किसी भी कारण से आपकी कक्षा को हटा दिए जाने पर इसे सहेजना भी सुरक्षित है, ताकि यदि आपको आवश्यकता हो तो [timer invalidate] कर सकते हैं।

+0

में आप उस प्रॉपर्टी 'weak', आप' nil' यह अपने आप की जरूरत नहीं है सुनिश्चित करें। आग लगने के बाद यह स्वचालित रूप से खुद को रिलीज़ कर देगा (मान लीजिए कि यह दोहराना नहीं था)। – Rob

1

हाँ, आप उपयोग कर सकते हैं: myTimer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO]; और फिर अपने viewDidDisappear [myTimer invalidate]

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