iOS: EXC_BAD_ACCESS вызвано запуском таймера в NSThread? - PullRequest
0 голосов
/ 17 октября 2011

В моем приложении произошли сбои При проверке журналов и использовании atos он точно сообщает мне, где я получаю сбой, и именно здесь я говорю моему NSRunLoop:

/**
 * Create a new thread for the timer
 *
 * @version $Revision: 0.1
 */
- (void)createTimerThread {
    NSThread *timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil];
    [timerThread start];
    [timerThread release];
}//end


/**
 * Start the actual timer
 *
 * @version $Revision: 0.1
 */
- (void)startTimerThread {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

    // Start timer
    self.countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];

    [runLoop run];// <--- Crash happened here
    [pool release];

}//end


/**
 * Update the counter
 *
 * @version $Revision: 0.1
 */
- (void)updateCounter:(NSTimer *)theTimer {

    // Does tons of timer stuff here

}//end

Как видите, сбой происходит на [runLoop run], но я понятия не имею, почему. Обычно это происходит во второй раз, когда я вызываю метод createTimerThread.

Что я здесь не так делаю? Все, что я хотел сделать, это запустить таймер в фоновом режиме, чтобы его не было в главном потоке, потому что мне нужно было обновить UILabel.

Должен ли я использовать что-то новое, например, Grand Central Dispatch (GCD)?

Ответы [ 2 ]

1 голос
/ 17 октября 2011

Вы сказали, что updateCounter обновляет UILabel и вызывается из таймера, который работает в фоновом потоке. Вы не можете этого сделать, вам нужно обновить представления пользовательского интерфейса в главном потоке.

Вы можете использовать executeSelectorOnMainThread или GCD (отправка в основную очередь). Я сравнил оба примера на этом посте:

GCD, потоки, поток программ и обновление пользовательского интерфейса

Эта статья о SO, в частности, содержит пример таймера bg с GCD:

iOS4 Создать фоновый таймер

Посмотрите на сообщение от mrwalker

0 голосов
/ 17 октября 2011

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

Не уверены, чего вы на самом деле пытаетесь достичь.Если вы делаете что-то вычислительно дорогостоящее на каждом таймере «таймера», то да, GCD будет лучшим выбором для использования блоков.

Возможно, вы могли бы дать нам некоторое представление о том, что вы делаете каждый тик и что вы отображаете в UILabel?

...