我正在使用AFNetworking来执行URL请求并在NSOperation中定义成功/错误块 - 所以这基本上是在NSOperation中运行异步过程。
我理解这种方法背后的警告,因为NSOperation将在调用委托方法之前提前终止,因此通过在主线程(相关帖子Asynchronous methods in NSOperation)上运行start()来实现一个建议的解决方案。
到目前为止,这一切都很好,我可以看到执行的顺序是正确的,即成功块执行,完成,然后调用dealloc。 UNTIL是否有这个(系统?)线程,名为__destroy_helper_block,它引用了NSOperation中的成功块,在此阶段已经解除了dealloc'd。究竟是什么? AFNetworking是否持有对该块的引用?
该线程上的调用堆栈是:
objc_release
_destroy_helper_block
_Block_release
__destroy_helper_block
_Block_release
start_wqthread
代码是
- (void) start {
...
void (^successHandler)(NSURLRequest *, NSHTTPURLResponse*, NSXMLParser *) = ^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
URLRequestParserDelegate *parserDelegate = [[URLRequestParserDelegate alloc]initWithChildDelegate:self];
// child to handle connection success
[self handleSuccess:request response:response];
// parse xml response data
[XMLParser setDelegate:parserDelegate];
[XMLParser parse];
[parserDelegate release];
[self finish];
}; // EXC_BAD_ACCESS on this line (?)
AFXMLRequestOperation *op = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request
success:successHandler failure:nil];
[op start];
}
答案 0 :(得分:0)
我只知道这可以通过ASINetworkQueue轻松完成:
- (void) process {
//Create downloadQueue
if (![self queue]) {
[self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
[[self queue] setDelegate:self];
[[self queue] setShouldCancelAllRequestsOnFailure:NO];
[[self queue] setQueueDidFinishSelector:@selector(queueFinished:)];
}
[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://www.YOURURL.com/"]];
[[self queue] addOperation:request]; //queue is an NSOperationQueue
NSLog(@"request added to operation");
[request setCompletionBlock:^{
NSLog(@"response headers %@", [request responseHeaders]);
NSLog(@"response body %@", [request responseString]);
}];
[request setFailedBlock:^{
NSLog(@"response error: %@", [[request error] localizedDescription]);
}];
}
- (void)queueFinished:(ASINetworkQueue *)queue{
NSLog(@"queueFinished:");
}