Jak używać NSTimer?

zamknięty . To pytanie i jego odpowiedzi są zamknięte , ponieważ pytanie jest off-topic, ale ma znaczenie historyczne. Obecnie nie przyjmuje nowych odpowiedzi ani interakcji.

Jak używać NSTimer? Czy ktoś może dasz mi instrukcje krok po kroku?

Author: bmajz, 2009-09-19

6 answers

Po Pierwsze chciałbym zwrócić uwagę na dokumentację Cocoa/CF (która jest zawsze świetnym pierwszym portem połączenia). Dokumenty Apple mają sekcję u góry każdego artykułu referencyjnego o nazwie "Przewodniki towarzyszące", która zawiera listę przewodników dla udokumentowanego tematu (jeśli istnieją). Na przykład z NSTimer, dokumentacja zawiera listę dwóch przewodników towarzyszących:

W twojej sytuacji, artykuł z tematami programowania timera prawdopodobnie będzie najbardziej przydatny, podczas gdy tematy wątków są powiązane, ale nie najbardziej bezpośrednio związane z dokumentowaną klasą. Jeśli spojrzeć na temat programowania timera, artykuł jest podzielony na dwie części:]}

  • timery
  • Używanie Timerów

W przypadku artykułów, które przyjmują ten format, często jest Przegląd klasy i do czego jest używana, a następnie niektóre przykładowy kod na jak go użyć, w tym przypadku w sekcji "Korzystanie z timerów". Istnieją sekcje "Tworzenie i planowanie timera", "zatrzymanie timera" i "zarządzanie pamięcią". Z artykułu wynika, że tworzenie zaplanowanego, nie powtarzającego się timera może być wykonane w następujący sposób:

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

Spowoduje to utworzenie timera, który zostanie wywołany po 2,0 sekundach i wywoła targetMethod: na self z jednym argumentem, który jest wskaźnikiem do instancji NSTimer.

Jeśli chcesz przyjrzeć się bardziej szczegółowo na metodę można odwołać się z powrotem do dokumentów, aby uzyskać więcej informacji, ale istnieje wyjaśnienie wokół kodu zbyt.

Jeśli chcesz zatrzymać czasomierz, który się powtarza (lub zatrzymać czasomierz, który się nie powtarza, zanim zostanie wywołany), musisz zachować wskaźnik do instancji NSTimer, która została utworzona; często będzie to zmienna instancji, aby można było odwołać się do niej w innej metodzie. Następnie możesz wywołać invalidate na instancji NSTimer:

[myTimer invalidate];
myTimer = nil;

Dobrą praktyką jest również nil out zmienna instancji (na przykład jeśli twoja metoda, która unieważnia timer, zostanie wywołana więcej niż raz, a zmienna instancji nie została ustawiona na nil, a instancja NSTimer została dealokowana, spowoduje to wyrzucenie wyjątku).

Zwróć również uwagę na punkt dotyczący zarządzania pamięcią na dole artykułu:

Ponieważ pętla run utrzymuje timer, z perspektywy zarządzania pamięcią zazwyczaj nie ma potrzeby przechowywania odniesienia do timera po zaplanował to . Ponieważ timer jest przekazywany jako argument, gdy określasz jego metodę jako selektor, możesz unieważnić powtarzający się timer, gdy jest to właściwe w tej metodzie . W wielu sytuacjach potrzebujesz jednak również opcji unieważnienia timera-być może nawet przed jego uruchomieniem. w tym przypadku musisz zachować odniesienie do timera, aby w razie potrzeby móc wysłać mu wiadomość o unieważnieniu. Jeśli utworzysz nieplanowany timer (patrz " nieplanowany Timers"), następnie należy zachować silne odniesienie do timera (w środowisku zliczonym przez odniesienia, zachowujesz go), aby nie został dealokowany przed użyciem.

 615
Author: Alex Rozanski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-19 18:10:44

Istnieje kilka sposobów użycia Timera:

1) zaplanowany timer i użycie selektora

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];
  • Jeśli ustawisz powtórzenia na nie, timer będzie czekał 2 sekundy przed uruchomieniem selektora, a następnie zatrzyma się;
  • jeśli repeat: tak, timer rozpocznie się natychmiast i będzie powtarzał wywołanie selektora co 2 sekundy;
  • aby zatrzymać timer, należy wywołać metodę timer 's-invalidate: [t invalidate];

Na marginesie, zamiast używając timera, który nie powtarza się i wywołuje selektor po określonym interwale, można użyć prostej instrukcji takiej jak:

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

Będzie to miało taki sam efekt jak powyższy przykładowy kod; ale jeśli chcesz wywołać selektor co n-ty raz, używasz timera z powtórzeniami:tak;

2) samoczynny timer

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];
  • spowoduje to utworzenie timera, który uruchomi się w określonym przez Ciebie terminie (w tym przypadku po minucie), a powtarza się co sekundę

3) nieplanowany timer i użycie wywołania

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];

I po tym, uruchamiasz timer ręcznie, kiedy potrzebujesz w ten sposób:

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



A dla przypomnienia metoda onTick: wygląda tak:

-(void)onTick:(NSTimer *)timer {
   //do smth
}
 331
Author: Woofy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-19 18:12:25

Coś takiego:

NSTimer *timer;

    timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
                     target: self
                     selector: @selector(handleTimer:)
                     userInfo: nil
                     repeats: YES];
 59
Author: ennuikiller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-19 17:30:37
#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
 5
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-17 17:49:17
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];

-(void)timerCalled
{
     NSLog(@"Timer Called");
     // Your Code
}
 5
Author: Mohit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-24 07:20:07

W odpowiedziach brakuje określonego timera o określonej porze dnia Tutaj jest na następnej godzinie:

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];

Oczywiście, zastąp "doRefresh" pożądaną metodą klasy

Spróbuj utworzyć obiekt kalendarza raz i uczynić wszystkie jednostki statycznymi dla wydajności.

Dodanie komponentu 1 do godziny działa dobrze, nie ma potrzeby testowania o północy (link )

 2
Author: gjpc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:32:31