views:

290

answers:

2

Hi All, Having a problem with NSURLConnection, if I create a NSURLConnection and call [connection connectionWithRequest] let it load a little then call [connection cancel] most of the time that works fine. However occasionally even after I call [connection cancel] the connection's delegate still gets called (which crashes the app). Googling around it looks like the problem here is a race condition in the runloop, I cancel the connection and release the delegate but before the runloop cycles it calls the delegate functions -> crash.

Is there a way for me to, after I call [connection cancel] confirm the connection has actually canceled? Even a crappy while() loop will do :(

+2  A: 

You should not release the connection & associated storage until it your delegate receives either a connectionDidFinishLoading: or a connectionDidFailWithError: message.

Delegates are normally retained by the object they're acting as delegate for, so the delegate shouldn't become invalid while the NSURLConnection is still referring to it, unless you're over-releasing it somehow.

David Gelhar
Thats a good rule of thumb, I'll try implementing this.
Shizam
A: 

You could use [connection setDelegate:nil] perhaps.

However, assuming you haven't created extra threads, there should be no way to get a race condition as the cancel call and event delivery will be on the same thread. As David hints at, I'd examine your code, check for any odd cases like connection getting set to nil before the cancel call, or problems with object retain/release calls.

This link might be useful if there's a possibility objects are being overreleased:

http://www.frogameleon.com/blog/last-night-an-iphone-zombie-nszombieenabled-saved-my-life

JosephH
Thanks for the suggestions guys but no luck, I double checked that all connections are canceled before setting to nil. I've been using zombies which is helpful but it just points to what I suspected that a connection that I've already canceled is calling its delegate. And if I set a variable in the delegate called BOOL triedCanceling to YES when I cancel it, in the delegate function that variable is set to NO which suggests race...
Shizam
Also, there is no [connection setDelegate:nil] unfortunately.
Shizam
Oh, yes, sorry about that, you're right.Are you using multiple threads? There is a warning about that here:http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/20001697-DontLinkElementID_2
JosephH
Nope, this isn't in a thread. I've found some other people who have the same problem but no solution was found: http://www.cocoabuilder.com/archive/cocoa/225771-nsurlconnection-cancel-doesn-release-its-delegate.html
Shizam