1

如果下载的文件已存在于文档文件夹中,如何取消 Alamofire 请求?

这是请求的代码:

Alamofire.download(.GET, fileUrls[button.tag], destination: { (temporaryURL, response) in
    if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
        let fileURL = directoryURL.URLByAppendingPathComponent(response.suggestedFilename!)
        self.localFilePaths[button.tag] = fileURL
        if NSFileManager.defaultManager().fileExistsAtPath(fileURL.path!) {
            NSFileManager.defaultManager().removeItemAtPath(fileURL.path!, error: nil)
        }
        return fileURL
    }
    println("temporaryURL - \(temporaryURL)")
    self.localFilePaths[button.tag] = temporaryURL
    return temporaryURL
}).progress { _, totalBytesRead, totalBytesExpectedToRead in
    println("\(totalBytesRead) - \(totalBytesExpectedToRead)")
    dispatch_async(dispatch_get_main_queue()) {
        self.progressBar.setProgress(Float(totalBytesRead) / Float(totalBytesExpectedToRead), animated: true)

        if totalBytesRead == totalBytesExpectedToRead {
            self.progressBar.hidden = true
            self.progressBar.setProgress(0, animated: false)
        }
    }
}.response { (_, _, data, error) in
    let previewQL = QLReaderViewController()
    previewQL.dataSource = self
    previewQL.currentPreviewItemIndex = button.tag
    self.navigationController?.pushViewController(previewQL, animated: true)
}

我还尝试创建一个请求变量,然后如果该文件存在但它不起作用var request: Alamofire.Request?则取消它。request?.cancel()

有人可以帮我解决这个问题吗?

4

2 回答 2

1

与其取消请求,IMO 你不应该首先提出它。您应该在启动 Alamofire 请求之前进行文件检查。

如果您绝对觉得需要启动请求,您始终可以在启动请求后立即取消。

var shouldCancel = false

let request = Alamofire.request(.GET, "some_url") { _, _ in
        shouldCancel = true
    }
    .progress { _, _, _ in
        // todo...
    }
    .response { _, _, _ in
        // todo...
    }

if shouldCancel {
    request.cancel()
}
于 2015-09-29T15:36:41.203 回答
0

TL; DR:在很多情况下,取消请求有点麻烦。据我所知,即使 Alamofire 也不保证会根据您的要求立即取消该请求。但是,您可以使用dispatch_suspendorNSOperation来克服这一点。

大中央调度 (GCD)

这种方式利用了函数式编程。

在这里,我们用低级编程来启发我们的方式。Apple 引入了一个很好的库,即 GCD,用于进行一些线程级编程。

你不能取消一个块,除非......你挂起一个队列(如果它不是主队列或全局队列)。

有一个 C 函数称为dispatch_suspend, (来自Apple 的 GCD 参考

void dispatch_suspend(dispatch_object_t object);

在调度对象上挂起块对象的调用。

您还可以dispatch_object_t使用dispatch_queue_create.

所以你可以在用户创建的队列中完成你的任务,你可以暂停这个队列以防止 CPU 做一些不必要的事情。

NSOperation(也是 NSThread)

这种方式利用面向对象接口的函数式编程。

苹果还介绍了NSOperation,面向对象的编程可能是对象,而它更容易应付。

NSOperation根据 Apple 的文档,它是一个抽象类,它将代码和数据关联起来。

为了使用这个类,你应该使用它定义的子类之一,或者创建你自己的子类:特别是在你的情况下,我想NSBlockOperation是那个。

你可以参考这个代码块:

let block = NSBlockOperation { () -> Void in
    // do something here...
}

// Cancel operation
block.cancel()

尽管如此,它也不能保证停止它正在做的任何事情。苹果还表示:

此方法不会强制您的操作代码停止。相反,它会更新对象的内部标志以反映状态的变化。如果操作已经执行完毕,则此方法无效。取消当前在操作队列中但尚未执行的操作可以比平时更快地从队列中删除操作。

如果你想利用标志,你应该阅读更多:响应取消命令

于 2015-09-29T12:10:54.800 回答