NSOperation中的块 [英] Blocks within NSOperation
问题描述
我正在使用AFNetworking执行URL请求并在NSOperation中定义成功/错误块-因此,这基本上是在NSOperation中运行异步过程.
I'm using AFNetworking to perform URL request and defining success/error blocks within NSOperation - so that's basically running asynchronous process within NSOperation.
我了解这种方法背后的警告,因为NSOperation会在调用委托方法之前过早终止,因此已通过在主线程上运行start()实现了建议的解决方案之一(相关文章NSOperation中的异步方法).
I understand the caveat behind this approach, being NSOperation would terminate prematurely before delegate methods are called and therefore have implemented one of the suggested solutions by running start() on the main thread (relevant post Asynchronous methods in NSOperation).
到目前为止,一切都很好,我可以看到执行顺序是正确的,即成功执行块,完成,然后调用dealloc.直到有一个名为__destroy_helper_block的(系统?)线程正在引用NSOperation中的成功块,该线程在此阶段已被取消分配.这到底是什么? AFNetworking是否保留对该块的引用?
So far that's all good, I can see that the order of execution is correct i.e. success block executes, done, then dealloc gets called. UNTIL there's this (system?) thread called __destroy_helper_block that is referencing success block in the NSOperation which at this stage has been dealloc'd. What exactly is this? Is AFNetworking holding reference to the block?
该线程上的调用堆栈为:
Call stack on that thread is:
objc_release
_destroy_helper_block
_Block_release
__destroy_helper_block
_Block_release
start_wqthread
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];
}
推荐答案
我只知道使用ASINetworkQueue很容易做到这一点:
I only know this is easily done with the 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:");
}
这篇关于NSOperation中的块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!