0

я попробовал наш следующий простой тест, чтобы понять вопросы QoS в Interaction between qualityOfService property of NSOperationQueue & NSOperation added to itdispatch_after не всегда работает

При этом, я бегу в странный вопрос, где код внутри 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
self.fromMainOp = [NSBlockOperation blockOperationWithBlock:^{ 
    ViewController *innerSelf = weakSelf; 
    while (![innerSelf.fromMainOp isCancelled]) 
    { 
     usleep(1000000) ; 
     NSLog(@"Main OP QOS is %ld",innerSelf.fromMainOp.qualityOfService); 
    } 
}]; 

Этот код выглядит очень подобно блокировке основной очереди, пока этот блок не выйдет. Если основная очередь заблокирована, то никакие блоки, запланированные в основной очереди, не будут выполнены.

+0

Thanks @bbum. Ты прав. Если я добавлю операцию в OperationQ, которая не является основной очередью, это будет отменено. Он также работает, если dispatch_after отправляется в другой очереди. Итак, это правильное понимание проблемы: вышеупомянутый блок выполняется на главной очереди. Следовательно, блок, отправленный dispatch_after, никогда не запускается, потому что он застрял за ним. –

 Смежные вопросы

  • Нет связанных вопросов^_^