2012-02-14 137 views
2

我正在使用AFNetworking來執行URL請求並在NSOperation中定義成功/錯誤塊 - 所以這基本上是在NSOperation內運行異步過程。NSOperation內的塊

我明白了這種方法背後的警告,NSOperation會在委託方法被調用之前提前終止,因此通過在主線程(相關文章Asynchronous methods in NSOperation)上運行start()來實現了其中一種建議的解決方案。

到目前爲止,這一切都很好,我可以看到執行的順序是正確的,即成功塊執行完成,然後dealloc被調用。直到有這個(system?)線程叫做__destroy_helper_block,它引用了NSOperation中的成功塊,在這個階段已經被解除分配。這究竟是什麼? 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

您可以啓用NSZombie,並檢查了其對象實際上是在釋放? – 2012-02-14 09:19:50

+0

啊耶謝謝,現在就試試。 – user1187378 2012-02-14 10:17:02

回答

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