具有异步请求的递归函数

recursive function with async request

我有一个带有异步请求的递归函数。如果请求成功,我想保存在一个数组中,但我不知道如何。 具体是一个上传文件的函数,如果这个函数得到一个文件夹,那么这个文件夹里面的文件也要上传。

我想过用 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,该函数也会被调用多次。 所以我认为 completionHandler 的想法是错误的。我还能如何实现这一点?

  1. var isDir: ObjCBool = ObjCBool(true) 因此,默认情况下,您将所有文件都视为目录,当 manager.fileExistsAtPath 失败时,您将获得深度递归,因为 isDirectory标志保持 TRUE:

    If path doesn’t exist, this value is undefined upon return

    来自 Apple 文档...

  2. var pathString = pathToFile.path! + "/" + fileName - 不确定你最终得到的是正确的路径。所以,你得到递归。检查你的 pathString

  3. manager.fileExistsAtPath 结果被忽略,所以,你在盲目上传...

解决问题并继续...

好的,我回答我自己的问题。

complitionHandler 的想法确实是错误的。就像我在问题中所说的那样,调用 complitionHandler 的次数与调用递归函数的次数一样多。如果你想在我的应用程序中收集响应或喜欢收集一些文件是否成功上传,你必须使用调度组。主要思想是将所有请求添加到该组中并等待所有请求完成。

实际上这意味着创建组:

let group = dispatch_group_create()

在调用递归函数之前输入组,然后每次函数调用自身:

dispatch_group_enter(self.group)

请求完成后离开群组,与您进入群组的次数一样多:

dispatch_group_leave(self.group)

等待所有工作完成:

dispatch_group_notify(group, dispatch_get_main_queue()) {
        //Do work here
    }