NSOperation中的块 [英] Blocks within NSOperation

查看:89
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆