2015-01-31 2 views
2

Я пытаюсь обновить структуру с многоуровневым вложенным обратным вызовом async, поскольку каждый обратный вызов уровня предоставляет информацию для следующей партии запросов, пока все не будет выполнено. Это похоже на древовидную структуру. И каждый раз я могу только перейти на один уровень ниже.Как изменить структуру с асинхронными обратными вызовами?

Однако первая попытка с параметром inout не удалась. Теперь я узнал причину, благодаря отличным ответам здесь: Inout parameter in async callback does not work as expected

Мои поиски еще предстоит решить. Единственный способ, которым я могу думать, - сохранить значение в локальном файле или постоянном хранилище и изменять его каждый раз. И после написания кода примера, я думаю, что глобальный 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) 
    } 
} 

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

Я думаю, что нет способа сделать это с закрытием, учитывая, как работает закрытие. Но все же хочется спросить и узнать лучший способ.

Спасибо.

+2

Вы покажите нам свой код? Как выглядит вложенное закрытие? –

+0

@ThomasKilian Да, я напишу пример кода как можно скорее, чтобы продемонстрировать, чего я хочу достичь, поскольку исходный код слишком длинный и беспорядочный; P – LiweiZ

+0

@LiweiZ Вы пришли к выводу о том, как наилучшим образом подойти к этому? Мне было бы интересно услышать, если это так. – jeffro37

ответ

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 работал для меня, когда ни один другой объект не делал.

Смежные вопросы