Reputation: 4612
I've edited this post to make it simpler to read, I think.
I need to call an NSUrlConnection after I've finished doing some intensive string manipulation in a dispatch_async block.
The URL I call has got .htaccess authentication on it, so I can't use a synchronous connection.
But the NSURLConnection delegate methods are not being called. I know the URL loads after about 5 seconds in the browser, and I've tested the code with a simple URL with no authentication and it makes no difference.
What is stopping the delegate methods being called?
This function does some string manipulation stuff, and takes a while to finish:
- (void)performSearch {
// set some defaults and work out if it is a valid search, setting bSearchOk
if (bSearchOk) {
// update some interface elements
self.msgBox.text = @"Translating...";
self.plateInput.enabled = NO;
self.searchProgress.hidden = NO;
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// create a new search
Search *oPlateSearch = [[Search alloc] initWithTerm:thisTerm];
// ...
// perform search... this calls a variety of slow and intensive functions
// ...
self.aFinalPlates = [oPlateSearch.aValidated copy];
self.aCurrentPlates = [oPlateSearch.aFinals copy];
dispatch_async( dispatch_get_main_queue(), ^{
[oPlateSearch release];
// make ajax call to check if plates can be bought
[self getPrices];
});
});
} else {
// hide results
self.searchResults.hidden = YES;
}
}
And this is the one called towards the end of the block above
/* call to get plate availability and prices */
-(void) getPrices {
// set return message
self.msgBox.text = @"Getting prices and availability";
// ...
// then I build my strRequest var, which is a valid working URL
// ...
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:strRequest]];
NSURLConnection *loginConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
NSLog('This will get logged');
if(loginConnection) {
NSLog('This will also get logged');
self.jsonSearchResponse = [[[NSMutableData data] retain] autorelease];
NSLog('And this will get logged, so it's not throwing errors');
} else {
NSLog(@"Failed to get search results");
}
}
Update: I've tried this as well, as it was an accepted in answer on another similar question, but it hasn't worked:
NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[loginConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
[loginConnection start];
Based on this question: Why NSURLConnection delegate methods don't get called, when using the global dispatch queue?
Upvotes: 3
Views: 12554
Reputation: 3150
I have started a SO post which shows how to use the NSURLConnection
with dispatch_async
and configure the NSRunLoop
NSURLConnection blocking wrapper implemented with semaphores
The piece of code that you would be interested in is:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
[NSURLConnection connectionWithRequest:request delegate:self];
while(!self.finished) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
});
and in the connectionDidFinishLoading
, set finished
to YES:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.finish = YES;
}
Upvotes: 4
Reputation: 4612
Someone from iphonedevsdk.com forum answered this for me:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/97415-dispatch_async-nsurlconnection.html
The answer was to use:
[self performSelectorOnMainThread:@selector(getPrices) withObject:Nil waitUntilDone:NO];
Upvotes: 4
Reputation: 104065
I think you're autoreleasing the connection and not keeping any references to it, so that it goes out of memory. Remove the autorelease call and see if the problem disappears. If it does, just find a way to release the connection when you're done with it, so that it does not leak.
Upvotes: 0