【问题标题】:Async task don't change external variable. Swift 3异步任务不会更改外部变量。斯威夫特 3
【发布时间】:2016-10-26 10:38:54
【问题描述】:

我无法从 URL 保存数据,因为函数在无限循环中。怎么修? 我的代码:

func getRegion2(){
    let method = "region/"

    var url = serviceUrl+method
    var myArray: [String]()
    while(url != nil){

        Alamofire.request(url).validate().responseJSON { response in
            switch response.result {
            case .success(let data):

                let nextUrl = JSON(data)["next"].stringValue
                url = nextUrl
                myArray = myArray + myArray
                print(nextUrl)

            case .failure(let error):
                print("Request failed with error: \(error)")
            }
        }
    }
    print(myArray)
}

如果在没有“while”的情况下运行,那么一切正常。

【问题讨论】:

  • 你为什么使用 while ?你的目的是什么?
  • 块是异步的。所以,你必须检查myArray = myArray + myArray 这一行。在此行之后打印。
  • @emresancaktar 我使用“while”,因为我不知道执行 Alamofire.request(url) 需要多少时间。第一步:从默认 url 下载数据。从数据中保存数组并检查 nextUrl。第二步:如果 nextUrl 不是 nil 则从 nextUrl 下载数据并添加数组等。
  • 搜索“异步”。

标签: ios swift swift3 alamofire


【解决方案1】:

一种可能的解决方案是结合递归函数和调度组(未测试):

func getRegion2(){
    let method = "region/"

    var url = serviceUrl+method
    var myArray: [String] = []

    let group = DispatchGroup()

    func getRegion(with url: String) {
        group.enter()
        Alamofire.request(url).validate().responseJSON { response in
            switch response.result {
            case .success(let data):

                let nextUrl = JSON(data)["next"].stringValue
                myArray = myArray + someArrayFromRespnse
                print(nextUrl)

                if nextUrl != nil {
                    getRegion(with: nextUrl)
                }

                group.leave()
            case .failure(let error):
                print("Request failed with error: \(error)")
            }
        }
    }

    getRegion(with: url)

    group.notify(queue: DispatchQueue.main) { 
        print(myArray)
    }
}

我会使用完成块:

func getRegion2(completion: () -> [String]?) {
    let method = "region/"
    var url = serviceUrl+method
    var myArray: [String] = []

    func getRegion(with url: String) {
        Alamofire.request(url).validate().responseJSON { response in
            switch response.result {
            case .success(let data):

                let nextUrl = JSON(data)["next"].stringValue
                myArray = myArray + someArrayFromRespnse
                print(nextUrl)

                if nextUrl != nil {
                    getRegion(with: nextUrl)
                } else {
                    completion(myArray)
                }

            case .failure(let error):
                completion(nil)
            }
        }
    }

    getRegion(with: url)
}

【讨论】:

  • 乐于助人!
猜你喜欢
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
相关资源
最近更新 更多