我在我的应用程序中使用AFNetworking,并且我正在尝试在我的进度HUD中实现“点击取消”功能。我有一个管理所有HTTP请求的单例类。如果点击进度HUD,我打电话:
[[[HTTPRequestSingleton sharedClient] operationQueue] cancelAllOperations];
但这并不像我需要的那样“取消”操作。我读了NSOperationQueue
docs并发现了这个:
取消操作对象会将对象留在队列中,但会通知对象它应该尽快中止其任务。对于当前正在执行的操作,这意味着操作对象的工作代码必须检查取消状态,停止它正在执行的操作,并将自己标记为已完成。对于排队但尚未执行的操作,队列仍必须调用操作对象的start方法,以便它可以处理取消事件并将自身标记为已完成。
关于cancelAllOperations
方法:
此方法向当前队列中的所有操作发送取消消息。排队操作在开始执行之前被取消。如果操作已在执行,则由该操作识别取消并停止正在执行的操作。
我的问题似乎特别涉及已经执行的操作,我想立即取消。使用AFNetworking,如何提醒应该取消的操作并丢弃有关请求的所有信息?
用于操作的代码
AFJSONRequestOperation *loginOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
//operation was successful
if (loginOperation.isCancelled)
{
//can't do this. variable 'loginOperation' is uninitialized when captured by block
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
//operation failed
}];
答案 0 :(得分:9)
经过整整一天的AFNetworking源代码挖掘后,事实证明我的操作没有取消的原因与操作本身无关,而是因为我一直在错误地开始操作。我一直在使用
[NSOperation start];
当我应该将它添加到我的HTTPRequestSingleton
的操作队列中时:
[[[HTTPRequestSingleton sharedClient] operationQueue] addOperation:NSOperation];
将其添加到队列中可以正确取消它,而无需检查isCancelled
属性。
答案 1 :(得分:3)
completionBlock
返回操作的main时要执行的块 任务完成。
- (void(^)(void))completionBlock返回值操作主要任务完成后要执行的块。这个块没有 参数并没有返回值。
讨论您提供的完成块在值时执行 由isFinished方法返回的更改为YES。因此,这个块是 在操作的主要任务之后由操作对象执行 已完成或取消。
检查操作isCancelled
属性以了解调用回调的原因。
查看初始化代码:
+ (AFJSONRequestOperation *)JSONRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON))failure
{
AFJSONRequestOperation *requestOperation = [[[self alloc] initWithRequest:urlRequest] autorelease];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (success) {
success(operation.request, operation.response, responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (failure) {
failure(operation.request, operation.response, error, [(AFJSONRequestOperation *)operation responseJSON]);
}
}];
return requestOperation;
}
要获得回调中的operation
var,您要做的是在setCompletionBlockWithSuccess
初始化之后使用JSONRequestOperationWithRequest:success:failure:
,这有点矫枉过正,更好的方法是复制代码并使用
AFJSONRequestOperation *requestOperation = [[[self alloc] initWithRequest:urlRequest] autorelease];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// ... here you can check `isCancelled` flag