iphone ios läuft in einem separaten Thread

96

Was ist der beste Weg, um Code in einem separaten Thread auszuführen? Ist es:

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

Oder:

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

Ich habe den zweiten Weg gemacht, aber das Wesley-Kochbuch, das ich gelesen habe, verwendet den ersten.

Mike S.
quelle

Antworten:

243

Meiner Meinung nach ist der beste Weg mit libdispatch, auch bekannt als Grand Central Dispatch (GCD). Es beschränkt Sie auf iOS 4 und höher, ist aber einfach und benutzerfreundlich. Der Code, mit dem Sie einen Hintergrund-Thread verarbeiten und dann etwas mit den Ergebnissen in der Hauptlaufschleife tun können, ist unglaublich einfach und kompakt:

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
    });
});

Wenn Sie dies noch nicht getan haben, sehen Sie sich die Videos von WWDC 2010 unter libdispatch / GCD / blocks an.

Jacques
quelle
Ich brauche es 3.0 kompatibel zu sein :(
Mike S
1
Dann sind Operationswarteschlangen wahrscheinlich die nächstbeste Lösung. Stellen Sie außerdem sicher, dass Sie nicht zu schnell in die Parallelität eintauchen. Versuchen Sie zunächst, Dinge mit einem Thread und einem Profil zu schreiben, um festzustellen, ob Sie Multithreading benötigen oder ob Sie Ihren Code mit einem Thread so gestalten können, dass er selbst effizienter ist. Für einfache Aufgaben können Sie manchmal mit performSelector: withObject: afterDelay: alles tun, was Sie brauchen, und alle Probleme vermeiden, die bei der Multithread-Programmierung auftreten.
Jacques
Es tut mir leid, dass ich das so viel später wiederbelebt habe, aber wenn ich einen Methodenaufruf mit performSelector: withObject: afterDelay erhalte, muss ich dann noch einen NSAutoReleasePool in der asynchronen Methode verwenden? Wenn der Hauptpool für die automatische Freigabe auf magische Weise verwendet wird, ist performSElector: afterDelay definitiv eine schnellere Option.
Mike S
Nein, da die Methode auf dem Hauptthread ausgeführt wird, der über einen eigenen Autorelease-Pool verfügt.
Jacques
4
@Joe Auf die Gefahr hin, etwas zu sagen, das Sie bereits wissen, sollten Sie sich nicht angewöhnen, Code zu schreiben, der Threads abbricht. Dies wird Ihnen oder Ihrer Karriere auf lange Sicht nicht helfen. In diesem Beitrag (oder in vielen ähnlichen) finden Sie Gründe, warum Sie Threads nicht beenden sollten.
MikeC
1

Der beste Weg für das Multithreading in iOS ist die Verwendung von 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
quelle
0

Ich würde alle Techniken ausprobieren, die die Leute gepostet haben, und herausfinden, welche die schnellste ist, aber ich denke, dies ist der beste Weg, dies zu tun.

[self performSelectorInBackground:@selector(BackgroundMethod) withObject:nil];
Bobby
quelle
Dadurch wird der Thread mit niedriger Priorität gestartet. Die Verwendung von gcd ist der beste Weg zum Einfädeln.
Karsten