iphone ios работает в отдельном потоке


96

Как лучше всего запускать код в отдельном потоке? Это:

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

Или:

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

Я делал второй способ, но в Поваренной книге Уэсли, которую я читал, используется первый.

Ответы:


244

На мой взгляд, лучший способ - это libdispatch, также известный как Grand Central Dispatch (GCD). Он ограничивает вас iOS 4 и выше, но он настолько прост и удобен в использовании. Код для выполнения некоторой обработки в фоновом потоке, а затем выполнения каких-либо действий с результатами в основном цикле выполнения невероятно прост и компактен:

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

Если вы еще этого не сделали, посмотрите видео с WWDC 2010 в libdispatch / GCD / blocks.


Мне нужно, чтобы он был совместим с 3.0 :(
Mike S

1
Тогда очереди операций, вероятно, являются следующим лучшим решением. Также убедитесь, что вы не слишком быстро погружаетесь в параллелизм. Попробуйте начать с написания однопоточных и профильных вещей, чтобы увидеть, нужно ли вам использовать многопоточность, или вы можете разработать свой однопоточный код, который будет более эффективным сам по себе. Для простых задач вы иногда можете делать все, что вам нужно, с помощью performSelector: withObject: afterDelay: и избегать всех проблем, связанных с многопоточным программированием.
Жак

Извините за то, что воскресил это намного позже, но если я создаю вызов метода с помощью performSelector: withObject: afterDelay, мне все равно нужно использовать NSAutoReleasePool внутри метода async? Если он волшебным образом использует основной пул автоматического выпуска, то performSElector: afterDelay определенно более быстрый вариант.
Mike S

Нет, потому что метод выполняется в основном потоке, у которого есть собственный пул автозапуска.
Жак,

4
@Joe Рискуя сказать что-то, что вы уже знаете, вы не должны иметь привычки писать код, который убивает потоки, это не поможет вам или вашей карьере в долгосрочной перспективе. Посмотрите этот пост (или многие другие), чтобы узнать, почему не нужно убивать темы.
MikeC

1

Лучший способ многопоточности в iOS - использовать 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

Я бы попробовал все методы, опубликованные людьми, и посмотрел, какая из них самая быстрая, но я думаю, что это лучший способ сделать это.

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

это запускает поток с низким приоритетом. Использование gcd - лучший способ многопоточности.
Karsten

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.