2011-06-30 4 views
1

J'ai une erreur étrange qui apparaît récemment. Le NSOperationQueue dit qu'il a 1 objet mais je ne peux pas accéder à l'objet NSOperation à l'intérieur.NSOperationQueue exception hors plage

if ([[queue operations] count] > 0) 
    op = [queue.operations objectAtIndex:0]; 

Mais pour une raison quelconque, il finit à l'exception suivante: indice 0 au-delà des limites de tableau vide »

Je comprends le message d'erreur mais je suis surpris que je vérifiais le compte de file d'attente avant de demander l'objet lui-même.

Des idées s'il vous plaît?

Répondre

5

Rappelez-vous que les opérations sont en mesure de fonctionner sur des threads séparés et sont généralement. Un NSOperationQueue a fait sa propre méthode pour obtenir le nombre appelé operationCount et fournit ce mot d'avertissement:

La valeur retournée par cette méthode reflète le nombre instantané de objets dans la file d'attente et les changements que opérations sont terminées . Par conséquent, au moment où vous utilisez la valeur renvoyée, le nombre réel d'opérations peut être différent. Vous devez donc utiliser cette valeur uniquement pour le guidage approximatif et ne doit pas compter sur elle pour énumérations d'objets ou d'autres calculs précis .

Ce que vous rencontrez est probablement un problème de simultanéité. Une chose à considérer est de copier le tableau des opérations.

NSArray *ops = [queue.operations copy]; 
if ([ops count] > 0) 
{ 
    op = [ops objectAtIndex:0]; 
    //You can check if it has finished using [op isFinished]; 
    //and do what you need to do here 
} 
[ops release]; 

Mise à jour:

Voici un exemple des raisons pour lesquelles vous pouvez voir ce qui se passe très souvent

//Set up and start an NSOperation 
... 

//Here your call to operations probably put some sort of lock 
//around operations to retrieve them but your operation also 
//finished and is waiting for your lock to complete to remove 
//the operation. The operations call probably returns a copy. 
if([[que operations] count] > 0) 
{ 
    //Now the operation queue can access its operations and remove 
    //the item with the lock released (it can actually access as early 
    //as before the call and count) 

    //Uh oh now there are 0 operations 
    op = [queue.operations objectAtIndex:0]; 

} 
+0

Vous voulez dire qu'entre vérifier le nombre et l'affectation de la variable il y a un tel haut chance pour l'opération de finir? Etrange dans ce cas car l'affectation op = est inutile et ne peut pas être utilisée du tout. – Teddy

+0

Yea concurrence est super n'est ce pas? C'est la raison de l'opération de copie, Si vous vouliez vraiment faire quelque chose avec la première opération, copiez les opérations comme dans mon exemple et ensuite vous pouvez utiliser 'op' en toute sécurité. Et si vous vous souciez si c'est fini ou non, appelez la méthode 'isFinished'. – Joe

+0

Nice. J'ai utilisé un exemple de pomme dans mon code, mais il semble que ce "copier" des choses devrait être noté. Pendant ce temps, j'ai résolu le problème sans utiliser l'instruction op = car il n'y avait pas vraiment besoin de cela. Merci encore, Joe. – Teddy

1

l'opération peut avoir complété entre les deux appels