iphone ios działa w osobnym wątku

96

Jaki jest najlepszy sposób uruchamiania kodu w oddzielnym wątku? Czy to:

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

Lub:

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

Robiłem drugi sposób, ale książka Wesley Cookbook, którą czytałem, używa pierwszego.

Mike S.
źródło

Odpowiedzi:

244

Moim zdaniem najlepszym sposobem jest libdispatch, czyli Grand Central Dispatch (GCD). Ogranicza Cię do iOS 4 i nowszych, ale jest tak prosty i łatwy w użyciu. Kod, który wykonuje pewne przetwarzanie w wątku w tle, a następnie robi coś z wynikami w głównej pętli uruchamiania, jest niezwykle łatwy i kompaktowy:

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

Jeśli jeszcze tego nie zrobiłeś, obejrzyj filmy z WWDC 2010 na libdispatch / GCD / blocks.

Jacques
źródło
Potrzebuję kompatybilności 3.0 :(
Mike S,
1
Wtedy kolejki operacji są prawdopodobnie kolejnym najlepszym rozwiązaniem. Upewnij się również, że nie zagłębiasz się w współbieżność zbyt szybko. Spróbuj zacząć od napisania rzeczy jednowątkowych i profilu, aby sprawdzić, czy musisz przejść na wielowątkowość, czy też możesz zaprojektować kod jednowątkowy, aby był bardziej wydajny samodzielnie. W przypadku prostych zadań możesz czasami zrobić wszystko, czego potrzebujesz, za pomocą performSelector: withObject: afterDelay: i uniknąć wszystkich problemów związanych z programowaniem wielowątkowym.
Jacques
Przepraszam za wskrzeszenie tego o wiele później, ale jeśli wywołam wywołanie metody za pomocą performSelector: withObject: afterDelay, czy nadal muszę używać NSAutoReleasePool wewnątrz metody async? Jeśli w magiczny sposób wykorzystuje główną pulę automatycznego zwalniania, to performSElector: afterDelay jest zdecydowanie szybszą opcją.
Mike S
Nie, ponieważ metoda jest uruchamiana w głównym wątku, który ma własną pulę automatycznego ponownego uruchamiania.
Jacques,
4
@Joe Ryzykując, że powiesz coś, co już wiesz, nie powinieneś nabrać nawyku pisania kodu, który zabija wątki, na dłuższą metę nie pomoże to tobie ani twojej karierze. Zobacz ten post (lub wiele podobnych), aby dowiedzieć się, dlaczego nie należy zabijać wątków.
MikeC
1

Najlepszym sposobem na wielowątkowość w iOS jest użycie 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
źródło
0

Spróbowałbym wszystkich technik opublikowanych przez ludzi i zobaczył, która jest najszybsza, ale myślę, że to najlepszy sposób na zrobienie tego.

[self performSelectorInBackground:@selector(BackgroundMethod) withObject:nil];
Konstabl
źródło
powoduje to uruchomienie wątku z niskim priorytetem. Używanie gcd to najlepszy sposób na wątkowanie.
Karsten,