Objective C выполняет цикл, чтобы остановить и перезапустить метод?

  1. Позволяет броскам быть найденными легко в Вашем коде с помощью grep или подобных инструментах.
  2. Делает его явным, какой брошенный Вы делаете и вовлекаете справку компилятора в осуществление его. Если Вы только хотите выбросить мыс константы, то можно использовать const_cast, который не позволит Вам делать другие типы преобразований.
  3. Броски по сути ужасны - Вы как программист взяли верх, как компилятор обычно рассматривал бы Ваш код. Вы говорите компилятору, "Я знаю лучше, чем Вы". При этом это имеет смысл, который выполнение броска должно быть умеренно болезненной вещью сделать, и что они должны перетерпеть в Вашем коде, так как они - вероятный источник проблем.
  4. См. Эффективный C++ Введение

8
задан compound eye 20 September 2010 в 04:53
поделиться

2 ответа

Вы можете использовать объект синхронизации, на котором находится ваш вторичный поток. На этой странице Apple указано, что есть средство под названием «Условия», которое может делать то, что вы хотите. Использование Condition или аналогичного объекта синхронизации позволит вашему потоку разбудить только тогда, когда есть работа, которую нужно выполнить (или когда пришло время для потока умереть).

7
ответ дан 5 December 2019 в 12:11
поделиться

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

- (IBAction) startThread:(id)sender
{
    self.renderThreadMode = render_run;
    label.text = @"doing stuff"; 
    self.backgroundThread = [[NSThread alloc] initWithTarget:self selector:@selector(keepDoingStuff) object:nil];
    [self.backgroundThread start];    
}

//Okay, this is where we start changing stuff
- (void)keepDoingStuff
{
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

        //A runloop with no sources returns immediately from runMode:beforeDate:
        //That will wake up the loop and chew CPU. Add a dummy source to prevent
        //it.

        NSRunLoop *runLopp = [NSRunLoop currentRunLoop];

        NSMachPort *dummyPort = [[NSMachPort alloc] init];
        [runLoop addPort:dummyPort forMode:NSDefaultRunLoopMode];
        [dummyPort release];
        [pool release];

        while (1) 
        {
                NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
                [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
                [loopPool drain];
        }
}

Хорошо, на этом этапе вы должны посмотреть на приведенный выше код и подумать: «Что ж, это может быть неплохо. спящий поток, но он ничего не делает. И это правда, но поскольку у него есть активный цикл выполнения, мы можем делать все, что основано на цикле выполнения, включая performSelector: onThread: withObject: waitUntilDone:

- (void) doStuffOnBackgroundThread
{
    [self performSelector:@selector(doStff) onThread:self.backgroundThread withObject:nil waitUntilDone:NO];
}

Когда вы вызываете вышеуказанный метод в вашем основном потоке (или любом другом потоке), он будет упорядочивать различные аргументы и ставить в очередь цикл выполнения указанного потока, пробуждая его по мере необходимости. В этом случае это вызовет пробуждение self.backgroundThread из режима runMode: beforeDate :, выполнение -doStuff, затем цикл возврата по циклу и возврат в спящий режим ожидания в runMode: beforeDate :. Если вы хотите иметь возможность разорвать поток, вы можете установить переменную в цикле while, как в своем коде, хотя помните, что поток уйдет, если он спит, если вы его не разбудите, поэтому, вероятно, лучше всего инкапсулировать это в методе, который устанавливает управляющую переменную через performSelector: onThread: withObject: waitUntilDone :, в качестве плюса, который будет означать, что переменная будет устанавливаться только из фонового потока, что упрощает проблемы синхронизации.

Хорошо, я думаю это решает вашу проблему, так что пора сделать обязательную пробку: Вы уверены, что хотите сделать это с помощью потоков? NSOperation и NSOperationQueue могут быть гораздо более простым решением, которое позаботится обо всех проблемах потоковой передачи за вас, если все, что вам нужно делать, это иногда ставить в очередь некоторые данные для обработки. Они будут планировать работу, управлять зависимостями и создавать / отключать потоки, а также заботиться обо всех вещах пробуждения / сна runloop.

7
ответ дан 5 December 2019 в 12:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: