Is there anyway to cancel a Facebook object's pending request?
I can't find any methods in Facebook.h, or a way to access the underlying NSURLConnection
object. If I press back on the navigation bar and the their is a pending asynchronous Facebook request, the request tries to send a message to a deallocated view
once the response has come, causing the application to crash.
EDIT As pointed out in Tim's answer to this question, this information is now obsolete with the newest releases of the Facebook iOS SDK.
There is no way to cancel a pending request. However, this shouldn't be crashing your app.
The
Facebook
class uses theFBRequest
class under the hood to make all of its REST or Graph API requests, and this is the class that ends up with a reference to your view (controller?) as its delegate property. Looking at the header forFBRequest
:The assign attribute in the property declaration makes it seem that it stores a weak-ref to your class, but then in FBRequest.m:
It clearly retains the delegate. So, in the normal flow of your application, when you think your view controller should be deallocated after being popped off the navigation stack, the
FBRequest
has ensured that it will still be alive to receive the response by taking ownership of it.This makes it seem like you might have other memory management issues elsewhere in the app.
For anyone who comes across this question, it appears that Matt's observation does not apply to the newest facebook-iphone-sdk. The parameters are no longer explicitly retained in the relevant method:
So memory management for the delegate falls back to the property declaration in the .h file:
This means a crash is now possible since the delegate object can be deallocated before the FBRequest is completed.
Update:
A possible workaround is suggested in this question to allow cancellation of pending FBRequests.
Update 2:
To avoid a crash in the case where the delegate gets deallocated before the FBRequest finishes, you need to cancel the active FBRequest's connection as you deallocate the delegate (which is basically what Matt suggests in the linked question). However (I'm not sure if this is new), you can do this directly to the FBRequest since it exposes it's NSURLConnection property. So, if you retain your FBRequest object in a property:
and save the request object when you make your call:
you can clean everything up in your dealloc:
Obviously, you should probably also release and nil the FBRequest property in the delegate methods once you have processed the response.