Как вернуть значения, на которые влияет поток в Swift4 - PullRequest
0 голосов
/ 03 мая 2018
 func getAll(completion: (([Foods]?, Error?) -> Void)?){      
        var foodWithEname: [Foods]?
        let food: Food? = Food()
        var sortedFood: [Foods]?
        food?.getFoods(){ (foodsArray, error) in
            sortedFood = foodsArray?.sorted{ (left, right) in   
                if let lh = left.hits  {  
                    if let rh = right.hits {
                        return left.hits! > right.hits!
                    }
                    return true
                } else {
                    if let rh = right.hits {
                        return false
                    }
                    return false
                }
            }


            for fa in foodsArray! {

                var f = Foods(fid: fa.fid, fname: fa.fname, hits: fa.hits, addr: fa.addr, ename: nil)

                food?.getEffectsById(fa.fid){ (effectsArray, error) in
                    //foodWithEname?.ename = effectsArray
                    print ("11111")

                    DispatchQueue.global().async {
                        f.ename = effectsArray
                        print ("2222")
                        foodWithEname?.append(f)
                    }
                }

                DispatchQueue.global().async (execute: {
                    print ("00000")

                })

            }
            print("3333")
            completion?(foodWithEname, nil)
        }
        print ("4444")
    }

Мне нужно вернуть значение foodWithEname в главное представление, но оно вернулось без значения из-за потока потока ...

Я не знаю, как контролировать поток замыканий.

Я вызвал функцию в MainView:

let food: Food? = Food()
food?.getAll(){ (foodsArray, error) in

        }

И результаты: 4444 3333 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222 11111 2222

Я хочу получить результаты, как показано ниже:

2222 00000 11111 2222 00000 11111 2222 00000 ... 3333

И значения Array должны быть в foodWithEname при завершении? (FoodWithEname, nil).

Пожалуйста, помогите решить эту проблему, спасибо!

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Во втором цикле вы отправляете несколько асинхронных вызовов в цикле, и в то время как результат ожидает, вы вызвали обработчик завершения, так что результат пуст.

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

Сделайте что-то подобное во втором цикле:

// Create dispatch group
let group = DispatchGroup()

for fa in foodsArray! {

    var f = Foods(fid: fa.fid, fname: fa.fname, hits: fa.hits, addr: fa.addr, ename: nil)

    // Enter in group just before the call
    group.enter()

    food?.getEffectsById(fa.fid){ (effectsArray, error) in
        //foodWithEname?.ename = effectsArray
        print ("11111")

        DispatchQueue.global().async {
            f.ename = effectsArray
            print ("2222")

            // Leave the group when task is completed
            group.leave()

            foodWithEname?.append(f)
        }
    }

    DispatchQueue.global().async (execute: {
        print ("00000")

    })
}
print("3333")

// Wait for all tasks to complete, and call the completion handler
group.notify(queue: DispatchQueue.main) {
    completion?(foodWithEname, nil)
}
0 голосов
/ 03 мая 2018

Вам нужно DispatchGroup для обработки многих асинхронных вызовов

func getAll(completion: (([Foods]?, Error?) -> Void)?){      
    var foodWithEname: [Foods]?
    let food: Food? = Food()
    var sortedFood: [Foods]?
    food?.getFoods(){ (foodsArray, error) in
        sortedFood = foodsArray?.sorted{ (left, right) in   
            if let lh = left.hits  {  
                if let rh = right.hits {
                    return left.hits! > right.hits!
                }
                return true
            } else {
                if let rh = right.hits {
                    return false
                }
                return false
            }
        }

      let dispatchGroup = DispatchGroup()

      for fa in foodsArray! {

            var f = Foods(fid: fa.fid, fname: fa.fname, hits: fa.hits, addr: fa.addr, ename: nil)

            dispatchGroup.enter()

            food?.getEffectsById(fa.fid){ (effectsArray, error) in

             f.ename = effectsArray

             foodWithEname?.append(f)

             dispatchGroup.leave()

            }


        }

        dispatchGroup.notify(queue: .main) {

             completion?(foodWithEname, nil)
        }


   }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...