/ / Problem z wieloma NSTimerami - Objective-c, macos, cocoa

Wiele problemów z NSTimers - cel-c, macos, kakao

Podklasowałem komponent (wygląda jak kółko i jest w nim obrazek (podklasa NSView)).

Chcę zmieniać obraz za każdym razem X (żeby wyglądał jak animacja).

Kiedy w moim głównym kontrolerze widoku rysuję 1 podklasę w ten sposób, wszystko działa dobrze, ale kiedy dodam więcej, obraz zmienia się znacznie szybciej z każdym.

(Odpalam zmianę obrazu za pomocą pliku NSTimer) Zakładam, że problem występuje, ponieważ mam wiele NSTimers w tej samej kolejce

Jednak próbowałem użyć

NSTimer *uiTimer = [NSTimer timerWithTimeInterval:(1.0 / 5.0) target:self selector:@selector(changePicture) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:uiTimer forMode:NSRunLoopCommonModes];

To nie rozwiązało problemu (zakładam, że nadal znajduje się w głównym wątku) Więc wymyśliłem NSThread Rozwiązanie

[NSThread detachNewThreadSelector:@selector(updateModel) toTarget:self withObject:nil];


- (void) updateModel
{

[NSTimer scheduledTimerWithTimeInterval:secondsBetweenUpdates
target:self
selector:@selector(changePicture)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] run];
}

Ma trochę inne zachowanie (ale nadal nie ma szczęścia, ponieważ mam więcej podklas, ponieważ szybciej zmienia się obraz).

Moją ostatnią sesją było to rozwiązanie:

// Update the UI 5 times per second on the main queue
// Keep a strong reference to _timer in ARC
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,     dispatch_get_main_queue());
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, (1.0 / 5.0) * NSEC_PER_SEC, 0.25 * NSEC_PER_SEC);

dispatch_source_set_event_handler(_timer, ^{
[self changePicture];
});

// Start the timer
dispatch_resume(_timer);

Zwykle się nie poddaję, ale próbuję to rozwiązać już od 3 dni ... I myślę, że potrzebuję i rady, jak to zrobić, aby zadziałało zgodnie z przeznaczeniem.

Odpowiedzi:

1 dla odpowiedzi № 1

Jeśli używasz GCD, polecam użycie dispatch_after, na przykład:

float delayTime = 0.2f;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(delayTime * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
[self changePicture];
});