Swift OperationQueue для URLSession - PullRequest
       60

Swift OperationQueue для URLSession

0 голосов
/ 25 июня 2019

Я разработчик Android, в настоящее время изучаю Swift. Можете ли вы помочь мне с OperationQueue, пожалуйста?

class ViewController: UIViewController {

     var movieArray :[Movie] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        let queue = OperationQueue()

        queue.maxConcurrentOperationCount = 1

        for index in 1...5
        {
            queue.addOperation {
            self.process(value: index)
            }
        }

    }

    func process(value:Int)
    {
        print("Start for: \(value)")

        let url = NSURL(string: URL_API+"\(value)")

        //fetching the data from the url
        URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in

            if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
            {

                if let resultArray = jsonObj.value(forKey: "results") as? NSArray
                {
                    //Some Code...

                }

                print("Finish for: \(value)")
            }
        }).resume()

        print("End for: \(value)")
    }

}

То, что я ожидал получить:

Start for: 1
Finish for: 1
End for: 1
Start for: 2
End for: 2
Finish for: 2
Start for: 3
Finish for: 3
End for: 3
Start for: 4
Finish for: 4
End for: 4
Start for: 5
Finish for: 5
End for: 5

То, что я получил, это:

Start for: 1
End for: 1
Start for: 2
End for: 2
Start for: 3
End for: 3
Start for: 4
End for: 4
Start for: 5
End for: 5
Finish for: 1
Finish for: 5
Finish for: 3
Finish for: 4
Finish for: 2

Они не последовательные, как я могу их так сделать?

Ответы [ 2 ]

2 голосов
/ 25 июня 2019

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

Порядок Start - Finish - End никогда не произойдет.
Из-за асинхронного поведенияпорядок одной задачи с данными всегда Start - End – Finish.

Вам нужен асинхронный Operation, описанный в этот ответ

В асинхронном Operation вызове finish() в блоке завершения задачи с данными.


Примечание:

Не использовать NS... классы в Swift, если есть собственные аналоги

  • NSURLURL
  • NSDictionary[String:Any]
  • NSArray[[String:Any]]

И не value(forKeyкоторый имеет особый функционал.Используйте ключ подписки dict["key"] или object(forKey.И опция чтения .allowFragments не имеет смысла в Swift, если ожидаемый тип является типом коллекции.Опустить параметр.

0 голосов
/ 25 июня 2019

Вам следует взглянуть на раздел Управление зависимостями в приведенном ниже документе для своего решения: https://developer.apple.com/documentation/foundation/operation или

см. Эту тему NSOperationQueue последовательная очередь FIFO

либо вы должны сделать логику, чтобы при вызове завершения / сбоя вашей первой операции вы добавляли новую операцию в очередь и сокращали задачу из стека задач.

...