iPhone iOS rodando em discussão separada


96

Qual é a melhor maneira de executar código em um thread separado? É isso:

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

Tenho feito da segunda maneira, mas o Wesley Cookbook que tenho lido usa a primeira.

Respostas:


243

Na minha opinião, a melhor maneira é com libdispatch, também conhecido como Grand Central Dispatch (GCD). Limita você ao iOS 4 e superior, mas é muito simples e fácil de usar. O código para fazer algum processamento em um thread de segundo plano e, em seguida, fazer algo com os resultados no loop de execução principal é incrivelmente fácil e compacto:

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

Se você ainda não fez isso, verifique os vídeos do WWDC 2010 em libdispatch / GCD / blocks.


Preciso que seja compatível com 3.0 :(
Mike S

1
Então, as filas de operação são provavelmente a próxima melhor solução. Além disso, certifique-se de não mergulhar na simultaneidade muito rapidamente. Tente começar escrevendo coisas com thread único e perfil para ver se você precisa usar multiencadeamento, ou se você pode projetar seu código de thread único para ser mais eficiente por conta própria. Para tarefas simples, às vezes você pode fazer tudo o que precisa com performSelector: withObject: afterDelay: e evitar todos os problemas que vêm com a programação multithread.
Jacques

Desculpe por ressuscitar isso muito mais tarde, mas se eu gerar uma chamada de método com performSelector: withObject: afterDelay, eu ainda preciso usar um NSAutoReleasePool dentro do método assíncrono? Se ele usar magicamente o pool de liberação automática principal, o performSElector: afterDelay é definitivamente uma opção mais rápida.
Mike S,

Não, porque o método está sendo executado no encadeamento principal, que possui seu próprio pool de liberação automática.
Jacques

4
@Joe Correndo o risco de dizer algo que você já sabe, você não deve adquirir o hábito de escrever código que mata threads, isso não ajudará você ou sua carreira no longo prazo. Veja esta postagem (ou muitas semelhantes) para saber por que não matar tópicos.
MikeC

1

A melhor forma de multithreading no iOS é usando 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

Eu tentaria todas as técnicas que as pessoas postaram e ver qual é a mais rápida, mas acho que essa é a melhor maneira de fazer isso.

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

isso inicia o thread em uma prioridade baixa. Usar o gcd é a melhor maneira de encadear.
Karsten

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.