我有一个带有异步请求的递归函数。如果请求成功,我想保存在数组中,但我不知道如何。 具体来说,它是一个上传文件的功能,如果该功能获得一个文件夹,也应该上传该文件夹中的文件。
我想过用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的想法是错误的。我怎么能意识到这一点?
答案 0 :(得分:1)
好的,我回答我自己的问题。
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
}
答案 1 :(得分:0)
private void startBeaconRangeFinderService() {
beaconManager.setRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, org.altbeacon.beacon.Region region) {
try {
if (beacons.size() > 0) {
for (Beacon b : beacons) {
processYourBeaconInThisMethod(b);
}
}
} catch (Exception ex) {
Log.e(TAG_BEACON_ACTIVITY, "Error was thrown: " + ex.getMessage());
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
} catch (RemoteException e) {
Log.e(TAG_BEACON_ACTIVITY, "Error was thrown: " + e.getMessage());
}
}
因此,您默认将所有文件视为dirs,当var isDir: ObjCBool = ObjCBool(true)
失败时,您会收到深度递归,因为 isDirectory 标记保持为TRUE:
如果路径不存在,则返回时该值未定义
来自Apple Doc ...
manager.fileExistsAtPath
- 不确定最终会得到正确的路径。所以,你得到了递归。检查 pathString
解决问题并继续......