Как убить/приостановить/закрыть асинхронный блок в GCD?

Я реализовал блок, который отправляется асинхронно с использованием GCD следующим образом:

__block BOOL retValue;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    retValue = [self GCDHandler:actionName WithServiceType:serviceType :arguments];
});

return retValue;

Как отменить такой блок, если он работает дольше, чем хотелось бы? Есть ли способ отменить блоки, отправленные GCD, или предоставить им тайм-аут?


person Baidyanath    schedule 15.02.2012    source источник


Ответы (2)


Нет встроенного способа отмены блоков GCD. Они скорее настроены и забыты. Один из способов, которым я делал это в прошлом, — предоставлять «токены» для блоков.

- (NSString*)dispatchCancelable:(dispatch_block_t)block
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        if (!checkIfCanceled)
            block();
    }
    return blah; //Create a UUID or something
}

- (void)cancelBlock:(NSString*)token
{
   //Flag something to mark as canceled
}
person Joshua Weinberg    schedule 15.02.2012
comment
Это на 100% правильно, хотя, если block() является длительной операцией, то предварительная проверка, вероятно, не даст вам желаемых результатов. Ответ состоит в том, чтобы разбить block() на более мелкие операции, каждая из которых может быть независимо отменена, или поместить проверки для checkIfCancelled в сам блок, чтобы он мог периодически проверять, что он все еще в порядке для запуска, или, если нет, раскручивать выполняемую операцию. и вернуться. - person jkh; 16.02.2012

Это зависит от того, что делает ваш GCDHandler. На сайте разработчиков Apple есть несколько довольно хороших видеороликов о GCD — возможно, вы захотите перейти на уровень выше (в Cocoa) и использовать NSOperationQueue и NSOperations (либо ваш собственный подкласс, либо NSBlockOperation). Все они построены поверх GCD, и уровень абстракции может быть более подходящим для того, что вы пытаетесь сделать (что вы не указываете - это сетевой запрос? и т. д.).

person Scott Corscadden    schedule 15.02.2012