简体   繁体   中英

ASIHTTPRequest popViewControllerAnimated: => delegate EXEC_BAD_ACCESS

I set the view controller to be the delegate of a local variable ASIHTTPFormDataRequest request .

But, tapping "Back" before the request has finished, pops and deallocates the view controller. So, when the request completes and sends the message -requestDidFinish: to the now nonexistent delegate, the app crashes with an EXEC_BAD_ACECESS exception.

How do I fix this crash?

  1. One way I could think of solving this is to set the delegate to nil immediately after the navigation controller pops it. But, if that's the solution, how do I do that? (ARC's weak references would be sweet right now.)

  2. Another way I can think of is to make request an instance variable of the view controller and call [request clearDelegatesAndCancel]; [request release]; [request clearDelegatesAndCancel]; [request release]; in the view controller's dealloc method. This approach is outlined in ASIHTTPRequest Example Code , but I've been advised it's best to make requests local variables instead of instance variables. And, this particular view controller is a settings table view controller and has 13 switches. For automatic saving to the server, each switch creates & sends a new request each time it's toggled. If I made ivars, I'd have to make 13. That's a lot of code!

Thoughts? Ideas?

I think the first question is: What do you want to happen if the user presses back after pressing a switch? ie. Should the http request be cancelled, or is it important that the request does get to the server? I'll assume for now that you do want to cancel them, as that seems to be implied in your question.

I've been advised it's best to make requests local variables instead of instance variables

I'm not sure if that was good advice - you almost always want requests to not be local variables so you can cope with cases like this.

For your case, you could consider using an NSOperationQueue .

Rough steps to do this would be:

  1. Create an NSOperationQueue in your view controller init.
  2. When you want to make a http request, add it to the ASIHTTPRequest queue instead of call startAsynchronous
  3. In dealloc, iterate the objects in the queue, calling [request clearDelegatesAndCancel]; for each one, and then release the queue.

That should solve the crash without needing 13 ivars!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM