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.

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.


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

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];

powoduje to uruchomienie wątku z niskim priorytetem. Używanie gcd to najlepszy sposób na wątkowanie.
Karsten,

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.