मैं NSTimer का उपयोग कैसे करूँ?


344

मैं एक का उपयोग कैसे करूँ NSTimer? क्या कोई मुझे कदम से कदम निर्देश दे सकता है?


1
मुझे pravinmagdum.wordpress.com/2010/12/30/how-to-use-nstimer पर पैरामीटरवार जानकारी मिली है, इस पर गौर करें .. आपके लिए उपयोगी हो सकता है

जवाबों:


616

सबसे पहले मैं कोको / सीएफ प्रलेखन पर आपका ध्यान आकर्षित करना चाहूंगा (जो हमेशा कॉल का एक महान पहला बंदरगाह है)। Apple डॉक्स में "कम्पेनियन गाइड्स" नामक प्रत्येक संदर्भ लेख के शीर्ष पर एक खंड होता है, जो प्रलेखित किए जाने वाले विषय के लिए मार्गदर्शकों को सूचीबद्ध करता है (यदि कोई मौजूद है)। उदाहरण के लिए, प्रलेखनNSTimer , दो साथी गाइडों को सूचीबद्ध करता है:

आपकी स्थिति के लिए, टाइमर प्रोग्रामिंग विषय लेख सबसे उपयोगी होने की संभावना है, जबकि थ्रेडिंग विषय संबंधित हैं, लेकिन वर्ग से संबंधित नहीं है, जो सीधे प्रलेखित है। यदि आप टाइमर प्रोग्रामिंग विषय लेख पर एक नज़र डालें, तो इसे दो भागों में विभाजित किया गया है:

  • टाइमर
  • टाइमर का उपयोग करना

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

[NSTimer scheduledTimerWithTimeInterval:2.0
    target:self
    selector:@selector(targetMethod:)
    userInfo:nil
    repeats:NO];

यह एक टाइमर है कि 2.0 सेकंड के बाद निकाल दिया और कॉल पैदा करेगा targetMethod:पर selfएक तर्क है, जो करने के लिए एक सूचक है साथ NSTimerउदाहरण।

यदि आप तब विधि के बारे में अधिक विस्तार से देखना चाहते हैं तो आप अधिक जानकारी के लिए डॉक्स पर वापस जा सकते हैं, लेकिन कोड के आसपास भी स्पष्टीकरण है।

यदि आप एक टाइमर को रोकना चाहते हैं जो एक है जो दोहराता है, (या आग लगने से पहले एक गैर-दोहराए जाने वाले टाइमर को रोकना), तो आपको उस संकेतक के लिए एक संकेतक रखने की आवश्यकता NSTimerहै जिसे बनाया गया था; अक्सर यह एक उदाहरण चर होने की आवश्यकता होगी ताकि आप इसे किसी अन्य विधि में संदर्भित कर सकें। तब आप उदाहरण invalidateपर कॉल कर सकते हैं NSTimer:

[myTimer invalidate];
myTimer = nil;

nilउदाहरण चर को बाहर करना भी अच्छा अभ्यास है (उदाहरण के लिए यदि टाइमर को अमान्य करने वाली आपकी विधि को एक से अधिक बार कॉल किया जाता है और उदाहरण चर को सेट नहीं किया गया है nilऔरNSTimer उदाहरण को हटा दिया गया है, तो यह एक अपवाद फेंक देगा)।

लेख के निचले भाग पर स्मृति प्रबंधन पर भी ध्यान दें:

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


ओके, एक सवाल, मैं अपने कोड के रूप में क्या डालूंगा जो हर दो सेकंड में निष्पादित किया जाएगा?
lab12

जब आप कॉल YESकरेंगे repeats:तो आप पास होंगे scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:। यदि आप ऐसा करते हैं, तो NSTimerउदाहरण के लिए एक संदर्भ रखना सुनिश्चित करें (यह विधि द्वारा वापस आ गया है) और मेमोरी प्रबंधन पर बिंदु का पालन करें जैसा कि ऊपर वर्णित है।
एलेक्स रोजानस्की

नहीं, मैं अपना कोड कहां रखूंगा जो हर 2 सेकंड में शुरू हो जाएगा? उदाहरण के लिए, मान लें कि मैं चाहता था कि यह हर 2 सेकंड में एक बीप शोर करे। मैं बीप शोर कोड कहां डालूंगा ..?
लैब 12

विधि में आप के साथ निर्दिष्ट करते हैं कि targetऔर selector। उदाहरण के लिए, यदि आपका लक्ष्य है selfऔर चयनकर्ता है timerMethod:, तो टाइमर फायर को timerMethod:परिभाषित करते समय विधि को कहा जाता है self। फिर आप उस विधि में जो भी कोड चाहते हैं, डाल सकते हैं, और टाइमर फायर होने पर विधि को बुलाया जाएगा। ध्यान दें कि टाइमर के आग लगने पर (जिसे आप पास के रूप में पास करते हैं selector:) नामक विधि केवल एक तर्क ले सकती है (जिसे जब कॉल किया जाता है तो NSTimerउदाहरण के लिए पॉइंटर है )।
एलेक्स रोजानस्की

क्षमा करें, का अर्थ है "परिभाषित self"
एलेक्स रोजज़स्की

331

टाइमर का उपयोग करने के कुछ तरीके हैं:

1) शेड्यूल किया गया टाइमर और चयनकर्ता का उपयोग करना

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];
  • यदि आप NO को दोहराते हैं, तो टाइमर चयनकर्ता को चलाने से पहले 2 सेकंड इंतजार करेगा और उसके बाद यह बंद हो जाएगा;
  • अगर दोहराना: हाँ, टाइमर तुरंत शुरू हो जाएगा और हर 2 सेकंड में चयनकर्ता को कॉल करना दोहराएगा;
  • टाइमर को रोकने के लिए जिसे आप टाइमर -इनवाइटिड विधि कहते हैं: [t अमान्य];

एक साइड नोट के रूप में, एक टाइमर का उपयोग करने के बजाय जो एक निर्दिष्ट अंतराल के बाद चयनकर्ता को दोहराता नहीं है और कॉल करता है, तो आप एक साधारण एप्लिकेशन का उपयोग कर सकते हैं जैसे:

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

इसका ऊपर के सैंपल कोड जैसा ही प्रभाव होगा; लेकिन अगर आप चयनकर्ता को हर बार कॉल करना चाहते हैं, तो आप दोहराव के साथ टाइमर का उपयोग करते हैं: हाँ;

2) स्व-निर्धारित टाइमर

NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
NSTimer *t = [[NSTimer alloc] initWithFireDate: d
                              interval: 1
                              target: self
                              selector:@selector(onTick:)
                              userInfo:nil repeats:YES];

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:t forMode: NSDefaultRunLoopMode];
[t release];
  • यह एक टाइमर बनाएगा जो स्वयं आपके द्वारा निर्दिष्ट कस्टम तिथि पर शुरू होगा (इस मामले में, एक मिनट के बाद), और हर दूसरे को दोहराता है

3) अनिर्धारित टाइमर और मंगलाचरण का उपयोग करना

NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(onTick:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:@selector(onTick:)];

NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
                      invocation:inv 
                      repeats:YES];

और उसके बाद, आप टाइमर को मैन्युअल रूप से शुरू करें जब भी आपको इस तरह की आवश्यकता हो:

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];



और एक नोट के रूप में, onTick: विधि इस तरह दिखती है:

-(void)onTick:(NSTimer *)timer {
   //do smth
}

ठीक है, लेकिन आप देखते हैं कि मैं अपने ऐप की पारदर्शिता को कम करना चाहता हूं, इसलिए मुझे नहीं पता कि NSTimer के साथ आवेदन कैसे करें
lab12

24
जी, ये लोग आज .. मुझे वोट दें क्योंकि आपने शुरू से निर्दिष्ट नहीं किया और हमें व्यर्थ में लिखने दिया!
वूफी

28
आपने व्यर्थ में नहीं लिखा। यह अच्छी जानकारी है!
विलक 2

विधि 2 में, "स्व-शेड्यूल किया गया टाइमर", मैं जब चाहूं, टाइमर को कैसे रोक सकता हूं?
सत्यम

1
@Satyamsvv, आप टाइमर को रोक कर आह्वान कर सकते हैं, एक और विधि कह सकते हैं: [टाइमर अमान्य]; टाइमर = नील;
किम्पॉय सिप

59

कुछ इस तरह:

NSTimer *timer;

    timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
                     target: self
                     selector: @selector(handleTimer:)
                     userInfo: nil
                     repeats: YES];

14
अभी भी मजबूत हो रहा है ... 2014 भी!
मुरुगनंथम के

5
#import "MyViewController.h"

@interface MyViewController ()

@property (strong, nonatomic) NSTimer *timer;

@end

@implementation MyViewController

double timerInterval = 1.0f;

- (NSTimer *) timer {
    if (!_timer) {
        _timer = [NSTimer timerWithTimeInterval:timerInterval target:self selector:@selector(onTick:) userInfo:nil repeats:YES];
    }
    return _timer;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

-(void)onTick:(NSTimer*)timer
{
    NSLog(@"Tick...");
}

@end

किसी तरह यह चक्र को बनाए रखता है, इसलिए MyViewControllerकभी नहीं निपटता है।
दर्र्सकी

5
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];

-(void)timerCalled
{
     NSLog(@"Timer Called");
     // Your Code
}

आपने यह कहाँ लिखा है
मोहित

1
@ जिग्नेश यह उत्तर केवल NSTimer का उपयोग करने के बारे में नहीं है कि इसे पृष्ठभूमि में कैसे उपयोग किया जाए
मोहित

मैंने बैकग्राउंड मेथड में लिखा है - (शून्य) एप्लिकेशनडीनएटरब्लैकग्राउंड (UIApplication *) एप्लीकेशन {}
जिग्नेश B

बार-बार मोड के साथ YES
जिग्नेश B

कॉलबैक पद्धति के हस्ताक्षर के बारे में Apple का प्रलेखन बहुत विशिष्ट है। तुम्हारा होना गलत है।
निकोलाई रुहे

2

उत्तर में दिन के टाइमर का एक निश्चित समय गायब है, यहाँ अगले घंटे पर है:

NSCalendarUnit allUnits = NSCalendarUnitYear   | NSCalendarUnitMonth |
                          NSCalendarUnitDay    | NSCalendarUnitHour  |
                          NSCalendarUnitMinute | NSCalendarUnitSecond;

NSCalendar *calendar = [[ NSCalendar alloc]  
                          initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *weekdayComponents = [calendar components: allUnits 
                                                  fromDate: [ NSDate date ] ];

[ weekdayComponents setHour: weekdayComponents.hour + 1 ];
[ weekdayComponents setMinute: 0 ];
[ weekdayComponents setSecond: 0 ];

NSDate *nextTime = [ calendar dateFromComponents: weekdayComponents ];

refreshTimer = [[ NSTimer alloc ] initWithFireDate: nextTime
                                          interval: 0.0
                                            target: self
                                          selector: @selector( doRefresh )
                                          userInfo: nil repeats: NO ];

[[NSRunLoop currentRunLoop] addTimer: refreshTimer forMode: NSDefaultRunLoopMode];

बेशक, अपनी कक्षा की इच्छित पद्धति के साथ "doRefresh" स्थानापन्न करें

एक बार कैलेंडर ऑब्जेक्ट बनाने की कोशिश करें और दक्षता के लिए अलाउंस को एक स्थिर बनाएं।

एक घंटे के घटक को जोड़ना ठीक काम करता है, मध्यरात्रि परीक्षण की कोई आवश्यकता नहीं ( लिंक )

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.