Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

robbieduncan

Moderator emeritus
Original poster
Jul 24, 2002
25,611
893
Harrogate
I'm having an issue where NSURLConnection seems to be causing my application to crash. If I have code something like this then my application crashes after the timeout period, always and without exception.

Code:
// currentConnection and downloadedData are instance variables
- (void) startDownload
{
	// URL is setup and valid 
	NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
	currentConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
	downloadedData = [[NSMutableData alloc] init];
	[request release];
	
	// Start the download
	[currentConnection start];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
	// Append the received data to the current data
	[downloadedData appendData:data];
}

- (void) downloadComplete
{
	[downloadedData release];
	downloadedData = nil;
	[currentConnection release];
	currentConnection = nil;
}

// parseData does exist and parses the downloaded HTML to extract data.  It deals with saving the parsed data to the data model
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
	[self parseData];
	[self downloadComplete];
}

As far as I can see this is valid code. But 30 seconds after the start call the app is crashed every single time. I think what is happening is that I am releasing the connection object (currentConnection) far quicker than the timeout as the download completes within that time. The timeout handler that NSURLConnection has setup then fires and causes the exception.

So has anyone else seen this? If so did you come up with a good solution? The only solution I can think of is to hold on to the connection object for at least as long as timeout and then release it afterwards...
 

robbieduncan

Moderator emeritus
Original poster
Jul 24, 2002
25,611
893
Harrogate
Ok so not releasing the connection or holding on to it for at least twice as long as the timeout makes no difference.

The signal is "EXC_BAD_ACCESS". The callstack that seems to be causing this is:

#0 0x9691f63e in timeoutConnection
#1 0x96d2fb45 in CFRunLoopRunSpecific
#2 0x96d2fcf8 in CFRunLoopRunInMode
#3 0x91f31460 in +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:]
#4 0x91ecdf1d in -[NSThread main]
#5 0x91ecdac4 in __NSThread__main__
#6 0x91d946f5 in _pthread_start
#7 0x91d945b2 in thread_start

Making the timout longer or shorter simply delays or speeds up the crash. Any ideas?

Edit to add: even worse I can't reproduce this on an actual iPhone!
Edit again: spoke too soon, had the wrong code loaded on the phone. Seems to hang the whole device!
 

robbieduncan

Moderator emeritus
Original poster
Jul 24, 2002
25,611
893
Harrogate
You need to implement - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error.

Thanks for the suggestion, but that is implemented as

Code:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
	// Something went wrong!
	[self downloadComplete];
}

I know that there is not an error: parseData is running and the UI updates. The only way parseData can get called is if connectionDidFinishLoading: gets called. So there is no failure of the connection. The connection successfully downloads the web page I want and then after whatever I set the timeout to in the NSURLRequest it kills the application.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Don't call start, because when you use initWithRequest:delegate:, the download begins immediately. If you don't want this, use initWithRequest:delegate:startImmediately:
 

robbieduncan

Moderator emeritus
Original poster
Jul 24, 2002
25,611
893
Harrogate
Don't call start, because when you use initWithRequest:delegate:, the download begins immediately. If you don't want this, use initWithRequest:delegate:startImmediately:

Perfect. That appears to have fixed the timeout issue, a different internal connection issue I was seeing and an occasional issue I was having with the data doubling up.

I owe you a pint...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.