Запуск NSTimer в NSThread?

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

+ (void)timerThread{

    timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil]; //Create a new thread
    [timerThread start]; //start the thread
}

//the thread starts by sending this message
+ (void) startTimerThread
{
    timerNSPool = [[NSAutoreleasePool alloc] init];
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(startTime:) userInfo:nil repeats:YES];
    //timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(startTime:) userInfo:nil repeats:YES];
    //[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    [runLoop run];
    [timerNSPool release];
}

+ (void)startTime:(NSTimer *)theTimer{

    if(timeDuration > 1)
        timeLabel.text = [NSString stringWithFormat:@"%d",--timeDuration];
    else{
        [self stopTimer];
        [delegate timeIsUp];
    }

}
+ (void) stopTimer{

    if(timer != nil)
    {       
        [timerThread release]; 
        [timeLabel release];
        [timer invalidate];
        timer = nil;
    }

}

У меня никогда не было проблем с запуском NSTimer в runLoop основного потока с автоматическим выпуском приложения. У меня утечка на [выпуск timerNSPool]; GeneralBlock-16 Malloc WebCore WKSetCurrentGraphicsContext

Причина утечки - это обновление пользовательского интерфейса из вторичного потока:

timeLabel.text = [NSString stringWithFormat:@"%d",--timeDuration];

Однако я добавил еще один метод updateTextLbl, затем я вызываю его, используя этот

[self performSelectorOnMainThread:@selector(updateTextLbl) withObject:nil waitUntilDone:YES];

в основном потоке. У меня вообще не было утечек, но это противоречит цели наличия второго потока.

Это мой первый пост, и я ценю любую помощь. Спасибо ... заранее ....


person Unis    schedule 18.01.2010    source источник


Ответы (2)


Вы обновляете свой пользовательский интерфейс в +startTime:, но этот метод не работает в основном потоке. Это может быть источником предупреждения WebCore, которое вы видите.

person Darren    schedule 18.01.2010
comment
На самом деле это может быть так, спасибо. Любая идея, как я могу попытаться обновить свой пользовательский интерфейс из вторичных потоков, не обращаясь к этим утечкам памяти? - person Unis; 18.01.2010
comment
Используйте -performSelectorOnMainThread: withObject: waitUntilDone :. Однако, если это все, что делает ваш таймер, нет смысла запускать его в отдельном потоке. - person Darren; 18.01.2010
comment
Единственная причина, по которой я хотел бы, чтобы таймер работал в собственном потоке, потому что я использую его постоянно для каждого хода игрока, поэтому он используется на протяжении всего времени выполнения приложения, также я заметил проблемы с производительностью при взаимодействии с пользовательским интерфейсом во время запуска таймер в основном потоке, поэтому я перешел во второй поток, любые советы приветствуются ... - person Unis; 20.01.2010

Вне манжеты NSRunLoop, который у вас там, кажется немного неуместным. Из документов:

В общем, вашему приложению не нужно создавать объекты NSRunLoop или явно управлять ими. Для каждого объекта NSThread, включая основной поток приложения, при необходимости автоматически создается объект NSRunLoop. Если вам нужно получить доступ к циклу выполнения текущего потока, вы делаете это с помощью метода класса currentRunLoop.

У вас есть таймер, запускающий поток, который получает текущий цикл выполнения и пытается запустить его. Вы хотите связать таймер с этим циклом выполнения?

По телефону:

(void) addTimer: (NSTimer *) aTimer forMode: (NSString *) режим

?

person David Sowsy    schedule 18.01.2010
comment
Я не создаю никакого NSRunLoop, я просто получаю ссылку на текущий цикл, который является циклом выполнения текущего потока. - person Unis; 18.01.2010