Is it OK to retain a delegate of a subclass of ASIHTTPRequest
?
I made a subclass of ASIHTTPRequest
called JSONRequest
. Each instance of JSONRequest
is its own delegate, handles the callbacks, and passes them on to jsonDelegate
, which is a private property of JSONRequest
, and responds to requestFinished:withResult:
, where result is an NSDictionary
representation of the JSON response. To do this, I overloaded setDelegate:
in JSONRequest
to do super.delegate = self; self.jsonDelegate = newDelegate
.
Is it OK to retain jsonDelegate
in this case because often jsonDelegate
is a view controller, which is sometimes dealloced while the request is loading if the user hits "Back," etc. I will release jsonDelegate
in JSONRequest
after calling the callback methods.
How do I know this is OK and will not cause a retain loop.
What's retaining the request? (The operation queue, perhaps? Who knows?)
In general, the "fire-and-forget-and-give-me-a-callback" method you seem to be proposing is a bad idea. If nothing is retaining the VC apart from the request, then (unless your app structure is a bit silly) the VC will never get to do anything with the data it receives, so there's no reason for it to continue.
It also feels wrong: Does the request own the VC, or does the VC own the request? I'd expect the latter, so the VC should also retain the request.
There are a couple of exceptions:
For these cases, I often work around it with a "weak proxy" class which doesn't retain its target (and I wrote a "weak timer" wrappers around NSTimer/CADisplayLink to make this a bit easier.)
What you're supposed to do is keep track of the requests that you've initiated and in dealloc, do something like
Similarly, you're supposed to unregister for notifications/actions/KVO callbacks at the appropriate time. There's an exception:
There are exceptions to the exception:
I know that this question is originally about ASIHTTPRequest, but people might stumble upon this thread and it might make them think that using ASIHTTPRequest is still best practice - it is not, infact development has stopped in 2011 AFAIK.
Using more modern HTTP libraries which use blocks by default (I prefer AFNetworking), all variables referenced in fail/success blocks are either copied or retained until the blocks are released. This will spare you this whole memory management headache - except if you use
self
in one of the blocks, then you will create a retain cycle until the blocks have been released.If your release is deterministic (if you promise it will always happen, even in the case of an error, a timeout, or some other sort of unexpected event - like the connection simply hanging indefinitely) - then this is fine (no retain loop).
In this case, the retain loop would always get broken at some point.