#ios #multithreading #concurrency #nsoperationqueue
#iOS #многопоточность #параллелизм #nsoperationqueue
Вопрос:
У меня есть два вопроса о многопоточности в iOS
- если я хочу имитировать 100 одновременных вызовов API, что означает, что эти 100 вызовов API запускаются одновременно, как мне это сделать?
Нравится, если что-то вроде этого
for i in 0..<100 {
//Start API call
}
или добавьте 100 операций в одну OperationQueue и установите максимальную одновременность выше 100, запустите операции в очереди
все это должно означать запуск вызова API один за другим, так как же запустить их одновременно? точно так же, как добавить 100 операций и запустить вместе
- Как добавлять и отслеживать объекты NSURLSessionDataTask в OperationQueue? Например, используйте метод waitUntilAllOperationsDone() для нескольких объектов NSURLSessionDataTask.
Я использую что-то вроде
dispatch_group_enter(group)
session.dataTaskWithCompletion({
dispatch_group_leave(group)
})
dispatch_group_notify()
Мне интересно, может ли это быть реализовано в NSOperationQeue, кажется, что каждый поток, созданный NSURLSessionDataTask, случайным образом создается системой, так как отслеживать его в NSOperationQueue?
Комментарии:
1. Это настолько широко, и здесь так много ответов, возможно, вы можете сузить его. Итак, давайте отступим назад и спросим, что вы пытаетесь сделать? Просто пытаюсь понять, как выполнять параллельные запросы API? Пытаетесь выполнить стресс-тестирование какой-либо веб-службы? И т.д.
Ответ №1:
Независимо от того, запускаете ли вы эти 100 задач простым вызовом какого-либо асинхронного метода или с использованием очереди операций, эффект аналогичен: технически не все они будут запускаться в одно и то же время, но они должны (с несколькими оговорками) запускаться достаточно близко друг к другу, так что, предполагая, что асинхронный вызов API не возвращается мгновенно, вы, безусловно, будете запускать их одновременно.
Обратите внимание, если используется API NSURLSession
, возможно, вам придется настроить httpMaximumConnectionsPerHost
свой NSURLSessionConfiguration
. Обычно оно ограничено некоторым разумным значением, и если вам нужно 100 одновременных задач (больше, чем вы когда-либо хотели бы использовать в производственной среде), возможно, вам придется скорректировать этот параметр.
Вы задаете несколько вопросов об очередях операций. ИМХО, нет особой пользы от введения очередей операций в это обсуждение. Фактически, один из основных вариантов использования операционных очередей заключается в достижении прямо противоположного, когда вы не хотите, чтобы они все выполнялись одновременно, а скорее хотите ограничить параллелизм чем-то разумным (например, 4 одновременно). Таким образом, очереди операций могут быть частью вашего конечного производственного решения, но не вводите его исключительно ради попытки выполнить множество запросов одновременно.
Также обратите внимание, что при попытке запустить кучу асинхронных задач в очереди операций вы не можете просто addOperationWithBlock
или добавить NSBlockOperation
. Вы должны создать асинхронный пользовательский подкласс NSOperation
, который устанавливает isAsynchronous
флаг и выполняет необходимый KVO isFinished
и isExecuting
. Это не сложно, но этого достаточно, чтобы я не стал внедрять это без крайней необходимости.
Что касается «уведомления» группы отправки в сравнении с очередью операций, да, вы можете добиться чего-то подобного, используя очереди операций. Вы можете просто создать некоторую операцию «завершения», которая зависит от завершения всех других операций, и добавить ее в некоторую очередь после того, как все остальные операции будут поставлены в очередь.