2016-06-22 2 views
0

Je souhaite exécuter quelques méthodes de mise en réseau à l'aide de NSOperation pour chacune d'elles et ajouter les opérations à une NSOperationQueue définie sur un fil arrière, je veux que les NSOperations se produisent en série.Comment utiliser NSOperationQueue et NSOperation pour appeler périodiquement des tâches de téléchargement sérialisées à l'aide d'un NSTimer en arrière-plan Thread

L'appel qui crée la file d'attente NSOperation est appelé périodiquement, toutes les 30 secondes à l'aide d'un NSTimer.

est ici un code snipped jusqu'à présent:

NSTimer *timer; 
NSOperationQueue *bgQueue; 

- (void)startdDownloadLoop{ 

    if (![self.timer isValid]){ 

     self.bgQueue = [[NSOperationQueue alloc] init]; 
     self.timer = [NSTimer scheduledTimerWithTimeInterval:30.0 
                 target:self 
                selector:@selector(updateDB) 
                userInfo:nil 
                repeats:YES]; 

    } 

} 

- (void)updateDB{ 

    //  Next code was removed since si similar to the call `[self.bgQueue cancelAllOperations];`, as @robinkunde suggested 
    //  for (NSOperation *operation in [self.bgQueue operations]) { 
    //   if (operation.isExecuting) { 
    //    [operation cancel]; 
    //   } 
    //  } 

    [self.bgQueue cancelAllOperations]; 


    self.bgQueue = [[NSOperationQueue alloc] init]; 
    self.bgQueue.maxConcurrentOperationCount = 1; 

    NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadCars]; 
    }]; 

    NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadPartsForAllCars]; 
    }]; 

    NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{ 
     [NetworkManager downloadEachPathSpecs]; 
    }]; 

    [self.bgQueue addOperation:blockOp1]; 
    [self.bgQueue addOperation:blockOp2]; 
    [self.bgQueue addOperation:blockOp3]; 

} 

Les méthodes NetworkManager sont POST/GET méthodes avec les gestionnaires d'achèvement, qui après avoir terminé le téléchargement, ils économisent la date dans DB puis mettre à jour l'interface utilisateur en utilisant un notification.

Mise à jour:

Depuis la confusion, je pensais à poster ma question réelle en ce qui concerne le code: placé comme suit

1- Si l'exécution du NSOperationQueue sera de série? 2

2 - Si j'appelle le [operation cancel] va arrêter l'exécution de l'opération?

3 - Si j'appelle le cancelAllOperations et que je le ré-initialise, est-ce la bonne façon d'effacer le courant NSOperationQueue?

+0

Il ne fera probablement pas ce que vous voulez. On peut supposer que chacune des méthodes 'download ...' s'exécute de manière asynchrone. Si c'est le cas, dès que l'opération de réseau est envoyée, alors le bloc se terminera et le prochain bloc soumis commencera à s'exécuter, même si la première opération de téléchargement n'est pas encore terminée. Il vaut probablement mieux utiliser un dispatch_group, ou encore mieux envoyer des notifications plutôt que d'interroger ce qui est cher en termes de trafic de batterie et de réseau – Paulw11

+0

En ce qui concerne les opérations d'annulation, il appartient à chaque bloc de vérifier la propriété des blocs 'isCancelled' et cesser le travail si cela est approprié.La file d'attente d'opération ne peut pas réellement annuler une opération, elle définit simplement la propriété pour indiquer à l'opération qu'elle doit s'annuler elle-même. Voir http://stackoverflow.com/questions/8113268/how-to-cancel-nsblockoperation – Paulw11

Répondre

1

1) Vous pouvez définir la propriété maxConcurrentOperationCount sur la file d'attente sur 1 pour garantir l'exécution en série.

2) Cela définit uniquement la propriété isCancelled sur l'opération. Le besoin d'agir sur ce changement et se déplacer à l'état fini afin qu'il puisse être retiré de la file d'attente. En ce qui concerne votre exemple spécifique: NSBlockOperation est considéré comme terminé lorsque tous les blocs attachés sont retournés. Cela signifie que si les appels à NetworkManager sont synchrones, le bloc retourne immédiatement, l'opération est considérée comme terminée et la file d'attente démarre l'opération suivante. Il est tout à fait possible que la file d'attente se termine avant la fin de la première opération réseau. Si vous voulez les exécuter un à la fois, ce n'est pas la façon de le faire.

Vous pouvez utiliser des opérations réseau synchrones, mais cela ne vous permettrait pas de les annuler.

Vérifiez cette réponse: NSURLSession with NSBlockOperation and queues

3) Ceci est lié à 2). Tous les cancelAllOperations est définie la propriété isCancelled sur toutes les opérations. Jusqu'à ce que ces opérations soient terminées, la file d'attente continuera à exister. Créer une nouvelle file d'attente sur la même propriété ne change pas cela.

+0

Merci @robinkunde pour votre réponse rapide Je vais changer mon code en conséquence en supprimant le for-loop supplémentaire, mais ma question est de savoir comment Je force l'arrêt d'une opération NS qui est toujours en cours? –

+0

J'ai mis à jour ma réponse. – robinkunde