NSTimer и обновление UI

Я пытался заставить мою игру работать правильно с 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 на [сливе из пула];

Я запустил код в инструментах и ​​до сих пор не понимаю, почему он выдает ошибку. Любые идеи?


person Jules    schedule 28.06.2010    source источник


Ответы (1)


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

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

person progrmr    schedule 28.06.2010
comment
Спасибо за ответ. Я думаю, что таймер блокируется, поскольку он работает в основном цикле выполнения потоков, поэтому, когда пользователь панорамирует карту, обновление пользовательского интерфейса блокирует таймер ?? Это ожидаемое поведение или я просто делаю это совершенно неправильно? Большое спасибо Жюль - person Jules; 28.06.2010
comment
Вы можете создать NSThread для запуска таймера, но я не думаю, что отображение карты должно блокировать основной поток. Я никогда не использовал mapview, поэтому не знаю, как он себя ведет. Вы изучали MKMapView docs? Может быть, вы захотите перефразировать свой вопрос: почему мой вид карты блокирует основную ветку? и вместо этого сосредоточьтесь на этом. - person progrmr; 28.06.2010
comment
Я обновил свой вопрос ... пожалуйста, посмотрите выше и спасибо за вашу помощь. (извинения за форматирование кода) - person Jules; 29.06.2010