如何使用异步回调修改结构?

时间:2015-01-31 17:12:43

标签: swift

我正在尝试使用多级嵌套异步回调更新结构,因为每个级别的回调都会为下一批请求提供信息,直到完成所有操作。它就像一个树形结构。每次我只能达到以下一级。

但是,使用inout参数的第一次尝试失败。我现在了解原因,感谢这里的好答案: Inout parameter in async callback does not work as expected

我的任务仍有待解决。我能想到的唯一方法是将值存储到本地文件或持久存储中,并且每次都直接修改它。在编写示例代码之后,我认为全局变量也可以帮助我解决这个问题。但我想最好的方法是为这个工作提供一个struct实例。对于每一轮请求,我将这一轮的信息存储在一个地方,以避免不同轮次同时工作造成的混乱。

使用下面的示例代码,只有全局var更新才有效。我相信其他两个失败的原因与我上面提到的问题相同。

func testThis() {
    var d = Data()
    d.getData()
}

let uriBase = "https://hacker-news.firebaseio.com/v0/"
let u: [String] = ["bane", "LiweiZ", "rdtsc", "ssivark", "sparkzilla", "Wogef"]
var successfulRequestCounter = 0

struct A {}

struct Data {
    var dataOkRequestCounter = 0
    var dataArray = [A]()

    mutating func getData() {
        for s in u {
            let p = uriBase + "user/" + s + ".json"
            getAnApiData(p)
        }
    }

    mutating func getAnApiData(path: String) {
        var req = NSURLRequest(URL: NSURL(string: path)!)
        var config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
        var session = NSURLSession(configuration: config)
        println("p: \(path)")
        var task = session.dataTaskWithRequest(req) {
            (data: NSData!, res: NSURLResponse!, err: NSError!) in
            if let e = err {
                // Handle error
            } else if let d = data {
                // Successfully got data. Based on this data, I need to further get more data by sending requests accordingly.
                self.handleSuccessfulResponse()
            }
        }
        task.resume()
    }

    mutating func handleSuccessfulResponse() {
        println("successfulRequestCounter before: \(successfulRequestCounter)")
        successfulRequestCounter++
        println("successfulRequestCounter after: \(successfulRequestCounter)")
        println("dataOkRequestCounter before: \(dataOkRequestCounter)")
        dataOkRequestCounter++
        println("dataOkRequestCounter after: \(dataOkRequestCounter)")
        println("dataArray count before: \(dataArray.count)")
        dataArray.append(A())
        println("dataArray count after: \(dataArray.count)")
        if successfulRequestCounter == 6 {
            println("Proceeded")
            getData()
        }
    }
}

func getAllApiData() {
    for s in u {
        let p = uriBase + "user/" + s + ".json"
        getOneApiData(p)
    }
}

好吧,在我的实际项目中,我在第一批回调中成功地在结构中附加了一个var,而在第二批回调中它失败了。但是我没能在示例代码中使它工作。我尝试了很多次,所以我花了这么长时间用示例代码更新我的问题。无论如何,我认为主要问题是为这项任务学习适当的方法。所以我暂时把它放在一边。

考虑到闭包是如何工作的,我猜没有办法用闭包来做。但仍然想要问及学习最好的方法。

感谢。

1 个答案:

答案 0 :(得分:0)

我所做的是使用inout NSMutableDictionary。

func myAsyncFunc(inout result: NSMutableDictionary){
    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_async(dispatch_get_global_queue(priority, 0)) {
        let intValue = result.valueForKey("intValue")
        if intValue as! Int > 0 {
            //Do Work 
        }
    }
    dispatch_async(dispatch_get_main_queue()) {
        result.setValue(0, forKey: "intValue")
    }
}

我知道你已经尝试过使用inout,但是当没有其他对象时,NSMutableDictionary为我工作。