NSOperation内的块

时间:2012-02-14 08:48:26

标签: objective-c asynchronous block nsoperation

我正在使用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];
}

1 个答案:

答案 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:");
}