NSTimer и обновление пользовательского интерфейса - PullRequest
2 голосов
/ 28 июня 2010

Я пытался заставить мою игру работать правильно с NSTimer.Я видел, что у многих людей была похожая проблема со мной, и мне просто нужно кое-что прояснить.

В основном у меня есть NSTimer, работающий в главном потоке, который обновляет изображения, которые представляют время, но у меня также есть mapView.Когда пользователь панорамирует карту, таймер блокируется.Мой вопрос: если я создам новый поток и добавлю таймер к его циклу выполнения, то при выполнении селектора (который обновляет пользовательский интерфейс) это снова не заблокирует поток таймера?Также я знаю, что это плохая практика - обновлять пользовательский интерфейс из вторичного потока, так как мне поступить?

ОБНОВЛЕНИЕ: Я думаю, что mapView блокировал таймер, поскольку они оба работали втот же цикл выполнения.Теперь я исправил это с помощью потока таймера с собственным циклом выполнения, однако это привело меня ко второй проблеме, из-за которой я чрезвычайно застрял !!Вот код ...

//called when I need to restart the timer
[NSThread detachNewThreadSelector:@selector(resumeTimer) toTarget:self withObject:nil];  


-(void) restartTimer {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    timer=[NSTimerscheduledTimerWithTimeInterval:1.
                                          target:self
                                        selector:@selector(dim)
                                        userInfo:nil
                                         repeats:YES];

    [self performSelectorOnMainThread:@selector(timerImageUpdate)
                           withObject:nil
                        waitUntilDone:NO];

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];

    [pool drain];
}

Этот код дает мне ошибку Bad_access на [канализационном пуле] ;

Я запустил код в приборах идо сих пор не могу понять, почему это дает мне ошибку.Есть идеи?

1 Ответ

2 голосов
/ 28 июня 2010

Если вы создаете поток для своего таймера, вам все равно придется выполнить обновление пользовательского интерфейса в основном потоке.Вы можете сделать это с помощью executeSelectorOnMainThread: withObject: waitUntilDone: NO , которое поставит в очередь вызов метода в главном потоке без блокировки потока таймера.

Однако, если runloop основного потока заблокирован панорамированием карты (почему?), Обновление пользовательского интерфейса все еще будет ожидать в очереди событий до тех пор, пока панорамирование карты не будет выполнено.

...