Вложенные асинхронные блоки кода в Swift

#ios #swift #asynchronous #concurrency

#iOS #swift #асинхронный #параллелизм

Вопрос:

Я пытаюсь вложить NSTimer.scheduledTimerWithTimeInterval вызов внутри асинхронного NSURLSession.sharedSession().dataTaskWithRequest в Swift 2.0, но блок кода внутри test , похоже, не оценивается.

Например:

 class testc{

    @objc func test()
    {
        print("hello");
    }

    func loop()
    {
        if let url = NSURL(string : "https://www.google.com")
        {
            let url_req = NSURLRequest(URL: url);

            let task = NSURLSession.sharedSession().dataTaskWithRequest(url_req)
            { data, response, error in

                 let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(testc.test), userInfo: nil, repeats: true)

            }

            task.resume()

        }


    }
}
  

Если мы инициализируем этот класс и запустим loop , ничего не произойдет, функция test никогда не оценивалась.

Комментарии:

1. Вы забыли task.resume()

2. Упс, это была опечатка. Исправлено.

3. у вас нет правильного ну, посмотрите мой ответ

4. поместите его в конец задачи, а не в конец функции

5. Вы правы, но я по-прежнему не получаю вызовов test функции.

Ответ №1:

Вам нужно внести два изменения в ваш код.

После создания dataTask. Вам нужно попросить его возобновить (), чтобы отправить запрос. Таймер должен вызываться в основном потоке.

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

Я добавил счетчик, чтобы проверить, срабатывает ли таймер повторно.

Смотрите обновленный код ниже.

     class testc{

    static var counter : Int = 0

    @objc func test()
    {   testc.counter  
        print("hello -> (testc.counter)");
    }

    func loop()
    {
        if let url = NSURL(string : "https://www.google.com")
        {
            let url_req = NSURLRequest(URL: url);

            let task = NSURLSession.sharedSession().dataTaskWithRequest(url_req){ data, response, error in

                dispatch_async(dispatch_get_main_queue(), { 
                    self.setupTimer()
                })

            }.resume()
        }
    }

    func setupTimer() {
        let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(testc.test), userInfo: nil, repeats: true)
    }

}


let theBoy = testc()

theBoy.loop()
  

Комментарии:

1. Кажется, что таймер срабатывает только один раз, когда я его запускаю, NSTimer.scheduledTimerWithTimeInterval должен срабатывать бесконечно, не так ли?

2. Да, вы правы, пожалуйста, смотрите Обновленный ответ. Таймер должен быть настроен и запущен в основном потоке.