iPhone iOS fonctionnant dans un thread séparé

96

Quelle est la meilleure façon d'exécuter du code sur un thread distinct? Est-ce:

[NSThread detachNewThreadSelector: @selector(doStuff) toTarget:self withObject:NULL];

Ou:

    NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                        selector:@selector(doStuff:)
                                                                          object:nil;
[queue addOperation:operation];
[operation release];
[queue release];

J'ai fait la deuxième façon, mais le livre de cuisine Wesley que j'ai lu utilise la première.

Mike S
la source

Réponses:

244

À mon avis, le meilleur moyen est avec libdispatch, alias Grand Central Dispatch (GCD). Cela vous limite à iOS 4 et supérieur, mais c'est tellement simple et facile à utiliser. Le code pour effectuer un traitement sur un thread d'arrière-plan, puis faire quelque chose avec les résultats dans la boucle d'exécution principale est incroyablement simple et compact:

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //
    //
    dispatch_async( dispatch_get_main_queue(), ^{
        // Add code here to update the UI/send notifications based on the
        // results of the background processing
    });
});

Si vous ne l'avez pas déjà fait, regardez les vidéos de la WWDC 2010 sur libdispatch / GCD / blocks.

Jacques
la source
J'en ai besoin pour être compatible 3.0 :(
Mike S
1
Ensuite, les files d'attente d'opérations sont probablement la meilleure solution suivante. Assurez-vous également de ne pas plonger trop rapidement dans la concurrence. Essayez de commencer par écrire des éléments avec un seul thread et un profil pour voir si vous devez passer au multithread, ou si vous pouvez concevoir votre code à un seul thread pour qu'il soit plus efficace par lui-même. Pour des tâches simples, vous pouvez parfois faire tout ce dont vous avez besoin avec performSelector: withObject: afterDelay: et éviter tous les problèmes liés à la programmation multi-thread.
Jacques
Désolé d'avoir ressuscité cela beaucoup plus tard, mais si je lance un appel de méthode avec performSelector: withObject: afterDelay, dois-je toujours utiliser un NSAutoReleasePool dans la méthode async? S'il utilise par magie le pool de libération automatique principal, alors performSElector: afterDelay est définitivement une option plus rapide.
Mike S
Non, car la méthode est exécutée sur le thread principal, qui a son propre pool de libération automatique.
Jacques
4
@Joe Au risque de dire quelque chose que vous savez déjà, vous ne devriez pas prendre l'habitude d'écrire du code qui tue les threads, cela ne vous aidera pas ou votre carrière sur le long terme. Voir ce post (ou beaucoup aiment ça) pour des raisons de ne pas tuer les fils.
MikeC
1

Le meilleur moyen pour le multithreading sous iOS est d'utiliser GCD (Grand Central Dispatch).

//creates a queue.

dispatch_queue_t myQueue = dispatch_queue_create("unique_queue_name", NULL);

dispatch_async(myQueue, ^{
    //stuffs to do in background thread
    dispatch_async(dispatch_get_main_queue(), ^{
    //stuffs to do in foreground thread, mostly UI updates
    });
});
Kusal Shrestha
la source
0

J'essaierais toutes les techniques que les gens ont postées et voir laquelle est la plus rapide, mais je pense que c'est la meilleure façon de le faire.

[self performSelectorInBackground:@selector(BackgroundMethod) withObject:nil];
Policier
la source
cela lance le thread avec une faible priorité. L'utilisation de gcd est le meilleur moyen pour le filetage.
Karsten