У мене ситуація, коли мені потрібно зробити два HTTPОтримуйте запити та обробляйте їх результати лише після закінчення обох. У мене є обробник завершення кожного запиту мережі, але це не корисно, оскільки я не знаю, коли дані з обох запитів будуть отримані.
Я маю обмежений досвід роботи з GCD, але тепер цеSwift 3 не працює, я намагаюся зрозуміти, як запустити кілька завдань і мати єдиний обробник для завершення. Моє дослідження показало, що GCD або NSOperationQueue може бути рішенням, яке я шукаю. Чи може хто-небудь допомогти підказати, який інструмент підходить до роботи та як може виглядати код у Swift 3?
Відповіді:
13 за відповідь № 1Ви повинні використовувати диспетчерські групи, входячи вгрупуйте перед тим, як надіслати запит, і залиште групу в обробнику для завершення запиту. Отже, давайте на секунду припустимо, що у вас був якийсь метод, який виконував асинхронний запит, але надав параметр обробника завершення, який був закриттям, яке буде викликано, коли буде виконано мережевий запит:
func perform(request: URLRequest, completionHandler: @escaping () -> Void) { ... }
Щоб запустити ці два паралельних запити та отримувати сповіщення, коли вони будуть виконані, ви зробите щось на кшталт:
let group = DispatchGroup()
group.enter()
perform(request: first) {
group.leave()
}
group.enter()
perform(request: second) {
group.leave()
}
group.notify(queue: .main) {
print("both done")
}
Зрозуміло, ваша реалізація perform(request:)
може суттєво відрізнятися (наприклад, можливо, вам потрібно буде завершити передачу даних назад), але модель є такою ж, незалежно від того, пишете ви власний мережевий код URLSession
або за допомогою Alamofire. Просто використовуйте групи GCD, входячи в групу під час створення запитів і залишаючи групу в обробнику асинхронного запиту на завершення.
-1 для відповіді № 2
Джерело: Як записати dispatch_after GCD у Swift 3?
Ви можете використовувати dispatch_group
для того. Наприклад (код ObjC):
dispatch_group_t group = dispatch_group_create();
//startOperation1
dispatch_group_enter(group);
//finishOpeartion1
dispatch_group_leave(group);
//startOperation2
dispatch_group_enter(group);
//finishOpeartion2
dispatch_group_leave(group);
//Handle both operations completion
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//code here
});