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

Я робив другий спосіб, але книга Кулінарії Уеслі, яку я читав, використовує перший.

Відповіді:


243

На мій погляд, найкращий спосіб - з 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 / блоках.


Мені потрібно, щоб він був сумісним з 3.0 :(
Mike S

1
Тоді черги операцій, мабуть, наступне найкраще рішення. Крім того, переконайтеся, що ви не занурюєтесь у змагання занадто швидко. Спробуйте почати з написання речей з однопотокової та профільної роботи, щоб побачити, чи потрібно вам перейти багатопотоково, чи ви можете спроектувати свій однопотоковий код, щоб бути більш ефективним самостійно. Для простих завдань іноді ви можете виконувати все необхідне за допомогою performSelector: withObject: afterDelay: і уникати всіх проблем, які поставляються з багатопотоковим програмуванням.
Jacques

Вибачте, що я воскресив це набагато пізніше, але якщо я породжую виклик методу за допомогою perforSelector: withObject: afterDelay, чи все-таки мені потрібно використовувати NSAutoReleasePool всередині методу async? Якщо він чарівним чином використовує основний пул автоматичного звільнення, то perforSElector: afterDelay - це, безумовно, швидший варіант.
Майк 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.