1

J'ai une tâche de "synchronisation" qui repose sur plusieurs "sous-tâches", qui incluent des opérations de réseau asynchrones, mais qui nécessitent toutes l'accès à un seul NSManagedObjectContext. En raison des exigences de threading de NSManagedObjectContext, j'ai besoin que chacune de ces sous-tâches s'exécute sur le même thread. En raison de la quantité de traitement effectué dans certaines de ces tâches, j'ai besoin qu'ils soient sur un fil de fond.Comment démarrer un NSRunLoop et m'assurer qu'un NSAutoreleasePool est vidé?

En ce moment, je lance un nouveau fil en faisant cela dans ma méthode singleton -init de l'objet SyncEngine:

[self performSelectorInBackground:@selector(initializeSyncThread) withObject:nil]; 

La méthode -initializeSyncThread ressemble à ceci:

- (void)initializeSyncThread 
{ 
    self.syncThread = [NSThread currentThread]; 
    self.managedObjectContext = [(MyAppDelegate *)[UIApplication sharedApplication].delegate createManagedObjectContext]; 
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop run]; 
} 

Est-ce la bonne façon de démarrer le NSRunLoop pour ce fil? Y a-t-il une meilleure façon de le faire? La boucle d'exécution doit uniquement gérer les sources 'performSelector', et elle (et son thread) doit être présente pendant toute la durée du processus.

Lors de la configuration d'un NSAutoreleasePool, devrais-je le faire en utilisant des observateurs de boucle de fonctionnement pour créer le pool de libération automatique et le vider après chaque passage?

Répondre

0

Je ne suis pas 100% sûr que ce soit la façon la plus efficace pour résoudre votre problème, mais je fais comme ça ...

Depuis les opérations de réseau asynchrone peut prendre différentes de temps pour compléter (ou timeout) Je garde une trace d'eux avec une variable d'instance (dans ce cas un BOOL appelé callComplete)

Lorsque le code de déclenchement du réseau reqeust est démarré, et mon NSURLConnection est parti et fait de la magie, j'attends l'appel à être complet comme ça.

while(!callComplete && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]){ 
    // Here you can perform other checks, like making sure the method isn't running forever (with a timeout variable) 
    // Just set callComplete to YES when done 
} 
0

En ce qui concerne la NSAutoreleasePool, je crée simplement un sur le début de mon sélecteur qui est exécuté en arrière-plan. Puis, une fois la boucle d'exécution terminée (et mes appels terminés), je relâche comme d'habitude avant de revenir.

+0

J'ai 7-8 méthodes (et peut-être en avoir plus) qui ont besoin d'un pool autorelease sur le thread d'arrière-plan. S'il y a un moyen de le configurer et de le drainer de la boucle d'exécution elle-même (comme CocoaTouch le fait pour le thread principal), ce serait certainement préférable. –

+0

Je pense que vous pouvez utiliser des observateurs de boucle d'exécution pour savoir quand le traitement d'un événement est terminé. Pour plus d'informations, consultez les documents Apple. – InFreefall

Questions connexes