Насколько легкий NSOperationQueue на Snow Leopard? - PullRequest
6 голосов
/ 03 октября 2009

Я работаю с некоторым кодом, который выполняет кучу асинхронных операций с различными обратными вызовами; Snow Leopard сделал это невероятно легко с помощью блоков и GCD.

Я звоню NSTask с NSBlockOperation вот так:

[self.queue addOperationWithBlock:^{
    NSTask *task = [NSTask new];
    NSPipe *newPipe = [NSPipe new];
    NSFileHandle *readHandle = [newPipe fileHandleForReading];
    NSData *inData = nil;
    [task setLaunchPath:path];
    [task setArguments:arguments];
    [task launch];

    while ((inData = [readHandle availableData]) && [inData length]) {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            // callback
        }];
    }

    [task waitUntilExit];
}];

Этот подход работает отлично. Это похоже на магию, если мои обратные вызовы правильно обрабатывают параллелизм.

Теперь я хочу иметь возможность объединить некоторые из этих вызовов; это внутри метода «обновить» объекта модели и может занять много времени. Если пользователь нажмет кнопку обновления, это не должно связывать машину и все такое.

Здесь я вижу дилемму реализации. Я могу создать целую кучу очередей - по одной для каждого типа вызова - и установить для их числа одновременных операций значение 1, а затем вызывать -cancelAllOperations всякий раз, когда наступает время для нового вызова.

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

Насколько тяжел NSOperationQueue? Является ли создание большого количества очередей плохим архитектурным решением? Есть ли лучший способ объединить эти задачи?

Ответы [ 3 ]

8 голосов
/ 03 октября 2009

Если вы беспокоитесь о производительности, не угадайте: измерьте, а затем устраните все обнаруженные узкие места. Добавление очередей просто; попробуйте и посмотрите, что Instruments расскажет вам о влиянии на производительность.

Основная причина создания нескольких очередей - в том случае, если у вас есть причины хотеть запускать и останавливать их. Если вы просто хотите воспользоваться преимуществами libdispatch, вы можете получить это, просто добавив операции в основную очередь.

1 голос
/ 03 октября 2009

Вы можете добавить несколько блоков в NSBlockOperation, который будет выполнен одновременно и может быть отменен отмена содержащей операции. Пока ваши отдельные задачи не должны быть сериализованы, это может работать.

0 голосов
/ 03 октября 2009

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

...