0

我尝试了下面的简单测试来了解NSOperationQueue 的 qualityOfService 属性和添加到它的 NSOperation 之间的交互中的 QoS 问题

在执行此操作时,我遇到了一个奇怪的问题,其中 dispatch_after 中的代码并不总是有效。有人可以帮我理解为什么案例 2 不起作用。

在这种情况下,dispatch_after 中的取消代码被执行

  NSBlockOperation *newOp = [NSBlockOperation new];
    __weak NSBlockOperation *weakOp = newOp;
    [newOp addExecutionBlock:^{
        NSBlockOperation *innerOp = weakOp;
        while (![innerOp isCancelled])
        {
            usleep(2000000) ;
            NSLog(@"New Op QOS is %ld",innerOp.qualityOfService);
        }
        NSLog(@"Exiting snce new Op is cancelled");
    }];
    [self.myCustomQ addOperation:newOp];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSBlockOperation *innerOp = weakOp;
        [innerOp cancel];
        NSLog(@"Cancelling block 2");
    });

但在这种情况下,它没有被执行

self.myMainQ = [NSOperationQueue mainQueue];
NSLog(@"QOS of main Q is %ld",self.myMainQ.qualityOfService);

__weak ViewController *weakSelf = self;
self.fromMainOp = [NSBlockOperation blockOperationWithBlock:^{
    ViewController *innerSelf = weakSelf;
    while (![innerSelf.fromMainOp isCancelled])
    {
        usleep(1000000) ;
        NSLog(@"Main OP QOS is %ld",innerSelf.fromMainOp.qualityOfService);
    }
}];
NSLog(@"QOS of main op is %ld",self.fromMainOp.qualityOfService);
[self.myMainQ addOperation:self.fromMainOp];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    ViewController *innerSelf = weakSelf;
    [innerSelf.fromMainOp cancel];
    NSLog(@"Cancelling operation");
});
4

1 回答 1

4
self.fromMainOp = [NSBlockOperation blockOperationWithBlock:^{
    ViewController *innerSelf = weakSelf;
    while (![innerSelf.fromMainOp isCancelled])
    {
        usleep(1000000) ;
        NSLog(@"Main OP QOS is %ld",innerSelf.fromMainOp.qualityOfService);
    }
}];

该代码看起来非常像它正在阻塞主队列,直到该块退出。如果主队列被阻塞,那么主队列上调度的任何块都不会被执行。

于 2016-10-17T00:55:47.987 回答