Любые блоки, которые были асинхронно отправлены в вашу очередь, прежде чем вы на самом деле вызовите dispatch_suspend (), будут запущены до того, как приостановка вступит в силу. В вашем коде вы запускаете несколько блоков асинхронно, поэтому некоторые из них, вероятно, все еще находятся в очереди, когда вы вызываете test (2), и эти блоки будут выполнены.
Если вы хотите отменить выполняемые задания, вам нужно сделать это в соответствии с вашей собственной логикой. GCD целенаправленно не предоставляет истинного API отмены. Вы могли бы сделать что-то вроде этого:
@interface Canceller
{
BOOL _shouldCancel;
}
- (void)setShouldCancel:(BOOL)shouldCancel;
- (BOOL)shouldCancel;
@end
@implementation Canceller
- (void)setShouldCancel:(BOOL)shouldCancel {
_shouldCancel = shouldCancel;
}
- (BOOL)shouldCancel {
return _shouldCancel;
}
@end
static void test(int a){
static Canceller * canceller = nil;
if(q){
[canceller setShouldCancel:YES];
[canceller release];
dispatch_suspend(q);
dispatch_release(q);
q=nil;
}
canceller = [[Canceller alloc] init];
q=dispatch_get_global_queue(0,0);
dispatch_async(q,^ {
while(![canceller shouldCancel]){NSLog(@"query %d",a);sleep(2);}
});
}
Таким образом, каждый блок будет хранить ссылку на объект, который знает, должен ли он прекратить работу.