У меня есть какой-то метод вычисления данных (пусть это будет «myMethod:»), и я хочу переместить вызов в другой поток, потому что я не хочу блокировать свою основную функциональность пользовательского интерфейса.Итак, начал делать некоторые исследования о том, как вызвать мой метод в другом потоке.Насколько я вижу, в настоящее время есть много разных способов сделать это.Вот список:
a) с использованием чистых потоков (доступно с iOS 2.0):
[NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self withObject:_myParamsArray];
b) с использованием простого ярлыка (доступно с iOS 2.0).Доступно из унаследованного NSObject, но метод также принадлежит классу NSThread:
[self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray];
c) с использованием нового подхода к очередям Grand Central Dispatch (доступно с iOS 4.0):
dispatch_async(dispatch_get_global_queue(0, 0),
^ {
[self myMethod:_myParamsArray];
});
d) каким-то образом, используя некоторые классы, такие как NSOperation, NSBlockOperation или NSOperationQueue, хотя и не уверен, как именно это сделать (некоторый пример был бы оценен)
В настоящее время я использовал случай "b", но мне интересно узнать о плюсах и минусахи другие соответствующие предложения по этому вопросу.
ОБНОВЛЕНИЕ: e) также найден другой способ выполнения подобных потоковых операций - Выполнить циклы .Вот выдержка из документов Apple:
Цикл выполнения - это цикл обработки событий, который вы используете для планирования работы и координации приема входящих событий.Цель цикла выполнения состоит в том, чтобы держать поток занятым, когда есть работа, и переводить его в спящий режим, когда его нет.
ИМХО, более или менее вы выполняете ту же задачуКак вызвать ваш метод в отдельном потоке для его асинхронной операции.
ОБНОВЛЕНИЕ2: У вас уже был некоторый опыт работы с NSInvocationOperation и NSOperationQueue, и ИМХО, это довольно удобно.Согласно документам Apple, GCD и NSOperations являются предпочтительным способом реализации многопоточности.А также, NSOperations работает на GCD, начиная с iOS 4.0.Короче говоря, вы создаете экземпляр NSIvocationOperation (как вызов вашего метода), затем создаете экземпляр NSOperationQueue и добавляете вызов в очередь.NSOperationQueue достаточно умен, вы можете создать несколько объектов NSIvocationOperation (обернуть ваши вызовы методов) и их в NSOperationQueue.В остальном уверен.NSOperationQueue определяет, сколько параллельных потоков необходимо для выполнения вызовов (NSInvocationOperation), и обрабатывает его для вас.Он может выполнить первый вызов в потоке A, затем второй в потоке B, третий в потоке C и далее в потоке B, так что вам не нужно об этом беспокоиться.Но если вы хотите, вы можете сказать, как максимальные потоки NSOperationQueue может использовать для выполнения вызовов (например, 1), но мне это не нужно.По умолчанию все задачи выполняются не в главном потоке, поэтому очереди операций по умолчанию асинхронны.Кроме того, если вы хотите выполнять вызовы методов (каждый из которых заключен в отдельный NSInvocationOperation) в строгой очереди, вы можете добавить зависимости и, таким образом, NSOperationQueue сохранит порядок вызова метода.Вот пример:
// wrap your method call into NSInvocationOperation object
NSInvocationOperation *currentOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(yourMethodCall) object:nil];
// _sharedOperationQueue is a shared NSOperationQueue
// get all executing operations from the queue and get the last operation
_lastOperation = [[_sharedOperationQueue operations] lastObject];
// check if _lastOperation is not nil
if (_lastOperation) {
// if not then add dependency, so the calls would be performed in a queue
[currentOperation addDependency:_lastOperation];
}
// say - execute my method (operation)
[_sharedOperationQueue addOperation:currentOperation];
_lastOperation = currentOperation; // mark as last operation for adding dependency to the next operation
// the queue will retain invocation operation so you will release
[currentOperation release];
..... you can create another NSInvocationOperation and add it to the queue....
Что касается RUNLOOP, тем не менее, иногда вы сталкиваетесь с ними, например, при запуске / планировании таймера или при выполнении соединений NSURL.ИМХО, цикл выполнения можно сравнить с очередью задач, выполняемых в одном потоке.IMHO, runloop - это указатель на поток, который работает как очередь: у него есть задачи, которые могут генерировать события, и они будут помещены в конец очереди в этом потоке.По умолчанию все задачи в вашем приложении выполняются в одном цикле выполнения - в одном потоке.Я говорю, что это указатель, потому что, когда ваше приложение генерирует события, тогда приложение должно знать, куда поместить это событие (сенсорное событие или обратный вызов другого делегата) для выполнения.Конечно, вы должны прочитать о runloops для более подробной информации, потому что это только мои мысли.