I have a singleton wrapper class called "Folio APIWrapperv2" that is responsible for handling all of my API data calls within my iPhone app.
This class implements ASIHTTPRequest in order to fetch JSON from my server. When an ASIHTTPRequest has finished, it calls requestFinished:. In this method, I have additional processing of the data that can take a couple of seconds to complete. It's not major, but it slows down the app slightly, as it's a blocking call. To fix this, I create a new thread using GCD. However, when this thread runs, I get the following error:
[FolioAPIWrapperv2 respondsToSelector:]: message sent to deallocated instance 0x245050
This function is being called in ASIHTTPRequest's "handleBytesAvailable" method at the line:
if ([[self delegate] respondsToSelector:[self didReceiveDataSelector]]) {
I'm not sure what's going on here. FolioAPIWrapperv2 is a singleton class, so it should never be deallocated. I've tried searching online to see what other issues people have had with threading and couldn't find a suitable solution. Does anyone have an ideas?
Are you setting the delegate to be an instance of the class or the class itself? The delegate must be an instance of a class.
Otherwise, if you're getting the output:
[FolioAPIWrapperv2 respondsToSelector:]: message sent to deallocated instance 0x245050
Then it seems likely that your class that should never be deallocated is getting deallocated.
Either way, at least one way to approach this is to add some debugging, eg, when you create the request:
NSLog("set delegate to %p", request.delegate);
and similar logging for self in the init/dealloc of your singleton.
Related
Sorry if this is a dumb question, but I'm debugging a dangling pointer issue in my App and I need to know - Is it possible for the app to resignActive without first enterBackground?
To becomeActive without first enterForeground?
My situation - I have class (called 'Connection') that manages all of the application's requests/connections. It needs to be available for as long as the app is alive, really.
In my -didFinishLaunchingWithOptions I init an instance of Connection and set some params. In my -applicationWillEnterBackground I suspend Connection's actions.
And, in my -applicationWillEnterForeground I check to see if the Connection instance still exists. If it does, simply resume actions, else a new one is created.
When I leave the app running for a while (an hour or so, with or without going back to the home screen), the app crashes with this error.
"2012-08-19 13:08:42.708 Picsilk[11108:707] *** -[Connection respondsToSelector:]: message sent to deallocated instance 0x24e120"
The class, 'Connection', is just a simple NSObject subclass, which manages an ASINetworkQueue instance and handles some specific needs I have for storing a user's tokens and authenticating requests to my api.
An instance of this class is created and managed by app delegate. My various view controllers use the app delegate to access the Connection, which automatically handles the queue (and non-queued requests as well)
Surely I'm missing something very simple and fundamental to my understanding of this SDK, please help. :]
The app can receive a UIApplicationWillResignActiveNotification when a call comes in or other notifications are presented. So, yes, it's possible "for the app to resignActive without first enterBackground".
I have a Objective-C class that makes an HTTP request and, after receiving a response, calls methods on its delegate. The class provides some convenience methods around the built-in NSURLRequest for my application.
My question is: how do I ensure that I release this object? Normally, an object's owner is responsible for ensuring that an object gets released. In this case, there's no obvious owner. I want to create an instance of this class, set its delegate, fire off the HTTP request, and then forget about it (I could be making several of these requests, so the only way to give it an owner would be to keep a list of the request objects in the calling object, which seems suboptimal).
One approach I've considered: when the HTTP response comes in, my object calls its delegate and then does [self autorelease]. The problem is that all clients have to remember not to release this instance (or else my object needs to call retain before it returns to the user).
Anyone have any good patterns for this?
Apple have already thought of this pattern. On the assumption that you are using NSURLConnection, check out the documentation for -initWithRequest:delegate: Here is what it says about the delegate parameter:
The connection retains delegate. It releases delegate when the connection finishes loading, fails, or is canceled.
[my emphasis]
So when you create the connection, set your object as the delegate. It won't go away until the connection is terminated for whatever reason, even if no other object of yours retains ownership.
By the way, the statement
there's no obvious owner
is false. You say your object has a delegate. The delegate is the obvious candidate to be an owner.
Sorry if this has been asked before, but I'm wondering what the best memory management practice is for NSURLConnection. Apple's sample code uses -[NSURLConnection initWithRequest:delegate:] in one method and then releases in connection:didFailWithError: or connectionDidFinishLoading:, but this spits out a bunch of analyzer warnings and seems sort of dangerous (what if neither of those methods is called?).
I've been autoreleasing (using +[NSURLConnection connectionWithRequest:delegate:]), which seems cleaner, but I'm wondering--in this case, is it ever possible for the NSURLConnection to be released before the connection has closed (for instance, when downloading a large file)?
This returns autoreleased NSURLConnection:
+[NSURLConnection connectionWithRequest:delegate:]
If you want to keep the reference you need to retain it. Once you are done then release it.
It does not help to autorelease already autoreleased object.
I assume the example code will somewhere retain the NSURLConnection and then release it when the connection fails, as shown in your example.
This returns allocated object that you have to take care of cleaning
-[NSURLConnection initWithRequest:delegate:]
Because the method is named init, the other one above does not have init in the name or copy so you don't have to worry about the memory management.
If your object internally creates NSURLConnection at some point and then releases it when connection is done or failed you should reset the reference to nsurlconnection to nil.
In your dealloc you should cleanup the NSURLConnection as well, if it is nil nothing will happen but if it is still allocated it will clean it up.
See apple doc about memory management - it's quite simple.
I ran into the situation where my class is making one asynchronous web call and the user requests another one (by moving a map) and can't seem to properly cancel the NSURLConnection. I have seen some solutions to manage multiple async calls, but I do not want to do that because once the second request is made I no longer care about the first. I see that there is a cancel method, but I tried only calling it when the connection is nil, but the connection never seems to become nil despite a release on that object. Does anyone have a code sample of a proper cancel of an async NSURLConnect?
I don't think you understand Objective C message passing or retain/release. Sending a retain or a release to an object will never cause the pointer you are holding for that object to become nil (though the object may no longer be valid). In other words:
id a = b;
[a release];
//since release never changes the value of a
assert(a == b);
Okay, so having said that, if somehow a release code change the value of object pointer you called it against to nil, then sending a another message to it would do nothing. Messages to nil are silently dropped. Remember, what you are holding is a pointer to the object, not the object itself.
Having said that, if you want to cancel an NSURLConnection. You have to send it the cancel before you release it (in general it is never correct to send message to objects after you have released them).
I really recommend you read Apple's Memory Management documentation.
The following concerns an iPhone app.
I want to use a singleton to handle an asynchronous URL request. I've got that covered but what is the best coding practice way to tell the singleton where to send the response when it is received? I need the response to be returned to the class which originally called the singleton.
Could I pass a pointer to the calling class to the singleton, along with the delegate method (of the calling class) to call when the response is received?
Thanks
First of all, singletons are usually a bad design and this looks exactly like a situation where you should not need a singleton. See Singletons are Pathological Liars by Miško Hevery and other articles on his blog. (I hope this does not look arrogant, getting rid of the singleton will probably make your design better and coding easier.)
Second, if I understand your question correctly, you could pass the singleton a selector that should be called after the singleton receives the data. The API in the singleton class could look like this:
- (void) download: (NSURLRequest*) request andTell: (id) delegate to: (SEL) doThis;
Then after you finish loading the data you would do:
[delegate performSelector:doThis withObject:receivedData];
Does this answer the question?