【问题标题】:AFNetworking 2.0 cancel specific taskAFNetworking 2.0 取消特定任务
【发布时间】:2013-09-30 20:10:03
【问题描述】:

我正在试用 afnetworking 2.0,只是想弄清楚如何取消特定任务。 旧的方法是使用类似的东西

[self cancelAllHTTPOperationsWithMethod:@"POST" path:@"user/receipts"]

但我在 2.0 中没有看到类似的东西

我创建了一个AFHTTPSessionManager 的子类,它使我可以访问待处理任务的数组,我可以直接取消它们,但我不知道如何从另一个任务中识别一个,所以我只能取消特定的任务。 任务确实有一个任务标识符,但这似乎不是我需要的。

NSString *path = [NSString stringWithFormat:@"user/receipts"];
[self.requestSerializer setAuthorizationHeaderFieldWithUsername:[prefs valueForKey:@"uuid"] password:self.store.authToken];
[self GET:path parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
            completionBlock(responseObject);
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            errorBlock(error);
        }];

现在,如果我只想取消此请求,我将如何处理?

【问题讨论】:

    标签: ios afnetworking afnetworking-2


    【解决方案1】:

    您可以将任务存储在一个变量中,以便以后访问它:

    NSURLSessionDataTask* task = [self GET:path parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
                completionBlock(responseObject);
            } failure:^(NSURLSessionDataTask *task, NSError *error) {
                errorBlock(error);
            }];
    

    然后只需使用[task cancel] 取消它。

    另一种方法是保存任务的任务 ID,然后向 URL 会话询问其任务并确定要取消的任务:

    // save task ID
    _savedTaskID = task.taskIdentifier;
    
    // cancel specific task
    for (NSURLSessionDataTask* task in [self dataTasks]) {
        if (task.taskIdentifier == _savedTaskID) {
            [task cancel];
        }
    }
    

    【讨论】:

    • @phix23 知道为什么 [task cancel] 在被取消时仍然调用成功回调吗?
    • 我没想过在 NSURLSessionDataTask 中声明 GET 方法。非常感谢!
    【解决方案2】:

    不需要保存,这是我的实现,使用你的 AFURLSessionManager 的子类来取消特定的请求:

    - (void)cancelAllHTTPOperationsWithPath:(NSString *)path
    {
        AFURLSessionManager * yourSessionManager = [self getSessionManager];
    
        [[yourSessionManager session] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
            [self cancelTasksInArray:dataTasks withPath:path];
            [self cancelTasksInArray:uploadTasks withPath:path];
            [self cancelTasksInArray:downloadTasks withPath:path];
        }];
    }
    
    - (void)cancelTasksInArray:(NSArray *)tasksArray withPath:(NSString *)path
    {
        for (NSURLSessionTask *task in tasksArray) {
            NSRange range = [[[[task currentRequest]URL] absoluteString] rangeOfString:path];
            if (range.location != NSNotFound) {
                [task cancel];
            }
        }
    }
    

    【讨论】:

    • 赞成,但是作为另一个请求路径的子字符串的路径呢?即“/item/1”和“/item/11”取消项目1也会取消11。...URL] path] isEqualToString:path]不是更好的比较吗?
    • 感谢您指出这一点......我使用了这种方法,以便如果用户想要取消所有具有相同上下文的任务,它可以轻松完成,即“/school/class/students”会取消对“/school/class/students/id001”到 ..id100 的所有请求,因此也没有中断循环。您的问题可以通过使用“/item/01”和“/item/11”来解决。无论如何,可以根据要求更改比较。
    【解决方案3】:

    您可以执行以下操作

    NSArray *operations = [[[MyClient sharedClient] operationQueue] operations];
    if(operations && operations.count > 0){
        for (NSOperation *operation in operations) {
            if([operation isKindOfClass:[AFHTTPRequestOperation class]]){
                AFHTTPRequestOperation *httpOperation = (AFHTTPRequestOperation *)operation;
                NSLog(@"%@", [[httpOperation request] URL]);
                //--- if this is your request then cancel it --> [httpOperation cancel];
            }
        }
    }
    

    其中 MyClientAFHTTPClient 的子级,而函数 sharedClient 是一个静态函数,它返回 MyClient

    【讨论】:

    • 感谢降级,但请注明原因分享知识。
    • 可能是因为您的解决方案使用了AFHTTPClient,它仅是 AFN 1.x。问题是针对 AFN 2.0。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    相关资源
    最近更新 更多