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

リクエストをキャンセルするのではなく、そもそもそれを行うべきではありません。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_suspendorを使用できます。NSOperation

グランド セントラル ディスパッチ (GCD)

この方法では、関数型プログラミングを利用します。

ここでは、低レベルのプログラミングについて説明します。Apple は、スレッドレベルのプログラミングを行うために、GCD とも呼ばれる優れたライブラリを導入しました。

キューを一時停止しない限り、ブロックをキャンセルすることはできません (メイン キューまたはグローバル キューでない場合)。

と呼ばれるC関数がありますdispatch_suspendAppleのGCDリファレンスから)

void dispatch_suspend(dispatch_object_t object);

ディスパッチ オブジェクトでのブロック オブジェクトの呼び出しを中断します。

dispatch_object_tまた、 を使用してキュー (誰であるか)を作成することもできますdispatch_queue_create

したがって、ユーザーが作成したキューでタスクを実行でき、CPU が不要なことをするのを防ぐためにこのキューを一時停止することができます。

NSOperation (NSThread も)

この方法では、オブジェクト指向インターフェースを介して関数型プログラミングを利用します。

Apple はNSOperation、オブジェクト指向プログラミングがオブジェクトである可能性がある一方で、対処がより簡単な も導入しました。

NSOperationApple のドキュメントによると、コードとデータを関連付ける抽象クラスです。

このクラスを使用するには、定義されたサブクラスのいずれかを使用するか、独自のサブクラスを作成する必要がありますNSBlockOperation

次のコード ブロックを参照できます。

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

// Cancel operation
block.cancel()

それにもかかわらず、それが何をしていても停止することを保証するものではありません。Apple は次のようにも述べています。

このメソッドは、オペレーション コードを強制的に停止しません。代わりに、オブジェクトの内部フラグを更新して、状態の変化を反映します。操作の実行が既に終了している場合、このメソッドは効果がありません。現在操作キューにあるがまだ実行されていない操作をキャンセルすると、通常よりも早く操作をキューから削除できます。

フラグを利用したい場合は、詳細を読む必要があります:キャンセル コマンドへの応答

于 2015-09-29T12:10:54.800 に答える