Blocks within NSOperation

一个人想着一个人 提交于 2019-12-11 01:42:19

问题


I'm using AFNetworking to perform URL request and defining success/error blocks within NSOperation - so that's basically running asynchronous process within 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).

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

Code is

- (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:


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


来源:https://stackoverflow.com/questions/9273954/blocks-within-nsoperation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!