2015-09-15 2 views
0

У меня есть рекурсивная функция с запросом async. Я хочу сохранить в массиве, если запросы были успешными, но я не знаю, как это сделать. Конкретно это функция для загрузки файлов, и если функция получает папку, а файлы внутри этой папки также должны быть загружены.Рекурсивная функция с асинхронным запросом

Я думал о реализации этого с completionHandler, то об этом:

func uploadFiles(pathToFile: NSURL) ->[Bool]{ 
    var suc: [Bool] = [Bool]() 
    self.uploadFileRec(pathToFile, suc: &suc){ 
     (result: [Bool]) in 
     println(result) 
    } 
    return suc 
} 

func uploadFilesRec(pathToFile: NSURL, inout suc: [Bool], completionHandler: (result: [Bool]) -> Void){ 
    var isDir: ObjCBool = ObjCBool(true) 
    var manager: NSFileManager = NSFileManager.defaultManager() 
    manager.fileExistsAtPath(pathToFile.path!, isDirectory: &isDir) 
    if(isDir){ 
     var error: NSError? = nil 
     let contents = manager.contentsOfDirectoryAtPath(pathToFile.path!, error: &error) as! [String] 
     for fileName in contents { 
      if(fileName != ".DS_Store"){ 
       var pathString = pathToFile.path! + "/" + fileName 
       var updatePathtoFile = NSURL(fileURLWithPath: pathString) 
       self.uploadFilesRec(updatePathtoFile!, suc: &suc, completionHandler: completionHandler) 
       completionHandler(result: suc) 
      } 
     } 

    } 
    else{ 
     asyncFileUpload(...){ 
      ... 
      suc.append(/*successful or not*/) 
     } 
    } 
} 

Но проблема в том, что Println получить называют не только один раз, но столько, сколько uploadFileRec дозвонились внутрь. Поэтому, если бы я вызывал другую функцию вместо println, функция также вызывалась бы много раз. Так что я думаю, что идея с завершениемHandler была неправильной. Как еще я могу это понять?

ответ

0

Ok я ответьте на мой собственный вопрос.

Идея с усложнениемHandler была действительно ложной. Как я уже говорил в вопросе, compliedHandler вызывается столько раз, сколько вызывается рекурсивная функция. Если вы хотите собрать ответы или как в моем приложении собирать, если загрузка некоторых файлов прошла успешно, вы должны использовать группу отправки. Основная идея заключается в том, чтобы добавить все запросы в эту группу и ждать, пока все не будут выполнены.

На практике это означает создать группу:

let group = dispatch_group_create() 

Введите группу перед вызовом рекурсивной функции, а затем каждый раз, когда функция называть себя:

dispatch_group_enter(self.group) 

Оставьте группу, когда запрос и столько раз, сколько вы входите в группу:

dispatch_group_leave(self.group) 

И ждите до l все работы:

dispatch_group_notify(group, dispatch_get_main_queue()) { 
     //Do work here 
    } 
0
  1. var isDir: ObjCBool = ObjCBool(true) так, вы лечите все файлы в директориях по умолчанию, и когда manager.fileExistsAtPath терпит неудачу вы получаете глубокую рекурсию, потому что isDirectory флага остается TRUE:

    Если путь не существует, это значение не определен после возвращения

    от Apple, Док ...

  2. var pathString = pathToFile.path! + "/" + fileName - не уверен, что вы получите правильный путь в конце. Итак, вы получаете рекурсию. Проверьте ваш pathString

  3. manager.fileExistsAtPath результат игнорируется, так, что вы делаете слепую загрузки ...

Fix, что вещи и продолжать идти ...

+0

Хорошо спасибо. особенно ваша жажда. Я этого не понимал. – boddAh234

+0

Есть ли у вас идея по моей проблеме с «получить успешный или не массив из функции рекурсивной асинхронности»? – boddAh234