Как остановить NSInvocationOperation? - PullRequest
9 голосов
/ 18 апреля 2009

У меня есть NSInvocationOperation, который загружает и анализирует серию NSXMLDocuments в фоновом режиме в ответ на мой пользовательский интерфейс.

Моя попытка остановить операцию Invocation - вызвать cancellAllOperations моего NSOperationQueue. Но, похоже, это не остановит выполнение вызова.

Есть идеи, как мне поступить с этой проблемой?

Ответы [ 4 ]

11 голосов
/ 12 августа 2009

ОБНОВЛЕНИЕ: Инструменты показывают много утечек, когда я делаю это. Действуйте с осторожностью! Я сохраню это здесь на случай, если я действительно что-то предприму, и кто-то еще может выяснить, как преодолеть препятствие утечки.

Вот извращенная идея, которую я пытаюсь повторить, набирая это:

Установите операцию как объект для NSInvocationOperation '* initWithTarget: селектор: объект: метод. Предполагая, что у вас уже есть NSOperationQueue (назовем его queue ):

NSInvocationOperation *operation = [NSInvocationOperation alloc];
operation = [operation initWithTarget:self selector:@selector(myOperation:) object:operation];
[queue addOperation:operation];
[operation release];

Обратите внимание, что мы должны разбить alloc на собственный вызов. В противном случае мы не можем установить объект на операцию !

Затем, в вашем методе операции, откиньте объект назад и посыпьте проверки для isCancelled по желанию. Например:

  - (void)myOperation:(id)object {
    NSInvocationOperation *operation = (NSInvocationOperation *)object;
    if ([operation isCancelled]) return;
    ...
  }

Убедитесь, что ваш селектор оканчивается двоеточием в вызове initWithTarget: ... , так как вы теперь будете передавать объект.

Пока все хорошо. Теперь, если я смогу заставить cancelAllOperations , я буду знать, действительно ли это работает. :)

8 голосов
/ 02 июня 2010

Вам необходимо проверить, является ли NSInvocationOperation isCancelled YES. Чтобы сделать это в NSInvocationOperation, вы можете использовать Наблюдение значения ключа:

Добавьте ваш объект как NSInvocationOperation isCancelled наблюдатель при запуске операции:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:<targetObj> selector:@selector(<targetMethod>) object:nil];
[operation addObserver:<targetObj> forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil];
[operQueue addOperation:operation];
[operation release];

Затем в targetObj внедрить

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

для отслеживания изменения isCancelled с помощью cancellAllOperations из NSOperationQueue. Здесь вы можете установить частный флаг, а targetMethod может проверить его и отменить при необходимости.

5 голосов
/ 02 мая 2009

Пост выше хорош, но для более прямого ответа на оригинальный вопрос: кажется, что вы не можете остановить объект NSInvocationOperation, потому что он не поддерживает отмены. Вам придется его подкласс.

3 голосов
/ 18 апреля 2009

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

В основном методе вашей операции вы должны проверять isCancelled и обрабатывать это состояние, когда вы фактически отменены.

Для получения дополнительной информации см. Создание и управление объектами операций в Руководстве по программированию потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...