Помогите с многопоточностью на iOS?

У меня есть приложение, использующее OpenEars и библиотеку Flite. Проблема в том, что библиотека Flite требовательна к ресурсам и зависает в моем приложении. Я подозреваю, что запуск Flite в фоновом потоке исправит ситуацию, но я не знаю, как это сделать.

Тем не менее, как реализовать фоновый поток в iOS?

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


person Moshe    schedule 05.12.2010    source источник
comment
Удалось ли вам оптимизировать библиотеку Flite OpenEars с помощью очередей или потоков?   -  person Rasman    schedule 16.12.2011
comment
@Rasman - Честно говоря, я не пробовал, был очень занят. Я работаю над многопоточностью в другом проекте, поэтому я могу вернуться к этому в ближайшее время.   -  person Moshe    schedule 16.12.2011
comment
Хорошо, в качестве продолжения я просто создаю свое приложение с очередями отправки, и пока оно работает хорошо. На самом деле все оказалось проще, чем я ожидал...   -  person Rasman    schedule 17.12.2011


Ответы (3)


Руководство по параллельному программированию от Apple — это хорошее чтение. Параллельное программирование — это не то, что вы, возможно, захотите подобрать, скопировав какой-нибудь пример кода из Интернета и взламывая его, пока не будете довольны. Полезно знать варианты и принципы, чтобы уберечь себя от неприятностей.


Возвращаясь к ответу через некоторое время, в настоящее время вы почти не ошибетесь, используя Grand Central Dispatch. Запуск задачи в фоновом режиме выглядит так:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self doSomeLongTask]; // 1
    dispatch_async(dispatch_get_main_queue(), ^{
        [self longTaskDidFinish]; // 2
    });
});

Длинная задача (1) будет выполняться в каком-то фоновом потоке, и я не знаю об этом, т.е. в этом потоке уже есть пул автоматического освобождения, вам не нужно заботиться о циклах выполнения и т. д. После завершения задачи код вызывает -longTaskDidFinish в основном потоке (2), чтобы вы могли обновить пользовательский интерфейс или что-то еще. Это часто используемая идиома.

person zoul    schedule 05.12.2010
comment
Что сказал Зоул; резьба тяжелая. Даже если ваш код работает при запуске, он все равно может быть очень и очень неправильным. - person bbum; 05.12.2010
comment
Скажите, как я могу попасть в эту тему из моего метода doSOmeLongTask? Например, мне нравится, как вы разместили. и внутри моего метода doSomeLongTask мне нужно кое-что сделать в конце этого потока - person Shial; 26.03.2014
comment
Что пойдет в [self.longTaskDidFinish]. В моем приложении в конце doSomeLongTask я изменяю переменную, чтобы указать, что кнопку можно нажать. Могу ли я изменить переменную в [self longTaskDidFinish] вместо того, чтобы изменить ее сразу после того, как я сделаю [self doSomeLongTask] - person Roymunson; 02.09.2016

Возможно, лучше всего воспользоваться этим руководством от Яблоко. Прочитал внимательно (минут 10-20) и "нарезал" всю свою заявку! Отлично!

person EDUARDO CAPANEMA    schedule 03.03.2012

Свифт 3

DispatchQueue.global(qos: .userInteractive).async {
    // Code to run on background thread

    // Switch to the main UI thread to display any results needed
    DispatchQueue.main.async {
        // Run code on main UI thread here
    }
}

Параметр qos означает качество обслуживания. Думайте об этом как о приоритете для вашего фонового потока:

  • .userInteractive (высший приоритет)
  • .userInitiated (когда есть несколько секунд)
  • .utility (когда вы можете потратить от нескольких секунд до нескольких минут)
  • .background (самый низкий приоритет - минуты/часы в запасе)
person Mark Moeykens    schedule 16.03.2017