CFRunLoopRun () vs [NSRunLoop run]

У меня есть объект NSRunLoop, к которому я прикрепляю таймеры и потоки. Он отлично работает. Остановка это совсем другая история.

Я запускаю цикл, используя [runLoop run] .

Если я пытаюсь остановить цикл, используя CRunLoopStop ([[NSRunLoop currentRunLoop] getCFRunLoop]) , цикл не остановится. Если я начну цикл с помощью CRunLoopRun () , он будет работать. Я также убедился, что вызов выполняется в правильном потоке (тот, в котором запущен мой собственный выполнить цикл). У меня есть e отладил это с помощью pthread_self () .

Я нашел архив списка рассылки, в котором разработчик сказал: «Не беспокойтесь об использовании CRunLoopStop () , если вы запустили цикл с помощью метода выполнения NSRunLoop ». Я могу понять, почему это так - вы обычно объединяете инициализаторы и финализаторы из одного набора функций.

Как остановить NSRunLoop , не «прибегая к CF»? Я не вижу метода stop в NSRunLoop . В документации говорится, что вы можете остановить цикл выполнения тремя способами:

  1. Настроить цикл выполнения для запуска со значением тайм-аута
  2. Сообщите циклу выполнения, чтобы он остановился, используя CFRunLoopStop ()
  3. Удалить все источники ввода , но это ненадежный способ остановить цикл выполнения, потому что вы никогда не узнаете, что именно застряло в цикле выполнения за вашей спиной

Ну, я уже пробовал 2. и есть "уродливое" ощущение, потому что у вас есть копаться в CF. 3. не может быть и речи - мне не нравится недетерминированный код.

Остается 1. Если я правильно понимаю документацию, вы не можете «добавить» тайм-аут к уже существующему циклу выполнения. Вы можете запускать новые циклы выполнения только с таймаутом. Если я запустил новый цикл выполнения, это не решит мою проблему, поскольку создаст только вложенный цикл выполнения. Я все равно вернусь в старую, такую ​​же, как я хотел остановиться ... да? Возможно, я неправильно понял это. Кроме того, я не хочу запускать цикл со значением тайм-аута. Если я это сделаю, мне придется найти компромисс между сжиганием циклов ЦП (низкое значение тайм-аута) и быстродействием (большое значение тайм-аута).

Вот настройки, которые у меня есть прямо сейчас (псевдокод):

Communicator.h

@interface Communicator : NSObject {
    NSThread* commThread;
}

-(void) start;
-(void) stop;
@end

Communicator.m

@interface Communicator (private)
-(void) threadLoop:(id) argument;
-(void) stopThread;
@end

@implementation Communicator
-(void) start {
    thread = [[NSThread alloc] initWithTarget:self 
                                     selector:@selector(threadLoop:)
                                       object:nil];
    [thread start];
}

-(void) stop {
    [self performSelector:@selector(stopThread)
                 onThread:thread
               withObject:self
            waitUntilDone:NO];
    // Code ommitted for waiting for the thread to exit...
    [thread release];
    thread = nil;
}
@end

@implementation Communicator (private)
-(void) stopThread {
    CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);
}

-(void) threadLoop:(id) argument {
    // Code ommitted for setting up auto release pool

    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];

    // Code omitted for adding input sources to the run loop

    CFRunLoopRun();
    // [runLoop run]; <- not stoppable with 

    // Code omitted for draining auto release pools

    // Code omitted for signalling that the thread has exited
}
@endif

Что мне делать? Является ли обычным / хорошим шаблоном возиться с CF? Я недостаточно хорошо знаю Фонд.Возможно ли вмешательство в слой CF опасно (в отношении повреждения памяти, несоответствий, утечек памяти)? Есть ли лучший образец для достижения того, чего я пытаюсь достичь?

15
задан Jörgen Sigvardsson 21 December 2011 в 13:26
поделиться