iPhone - changing a delegate may cause crash for async calls?
I have a class that instanciate another class and works as a delegate for that second class. That second class is "free" and is not retained by the first one.
That second class sends async HTTP requests and listen for their response.
When a response is received, it is parsed, and the result is repackaged and sent to one of the delegate methods. Once the delegate is called, the second class instance release itself. End of the show.To be sure to get the server answer, when the first class enters in dealloc (for any reason), it changes the delegate property of the second one to route the answer to the applicationdelegate.
But... when changing that delegate attribute, I think there is a chance that the http answer that is async may collide with the dealloc process of the first class. So the first class would receive an answer while it is deallocating. In that case, the first class would receive an answer it cannot manage (may probably crash), and the second one would never see that the delegate had开发者_如何学JAVA changed just after the call has been sent to the first class.
How would you concretly manage that problem ?
Here is a schema of the process :
- AppDelegate creates A1, A2, A3.
- each Ax create a B instance object (B1, B2, B3 that send HTTP requests), and each Ax is defined as a delegate of Bx
- at this point, all A and B class instance may have their lives
- if a Ax instance dies, the Bx class may send the answer to the appdelegate instead of the Ax instance
Your have a problem if A is a delegate for B, but A is not allowed to retain B.
- B must known that is delegate (A) is still around, or set to
nil
when needed. - A must know that B is still around, or else it can not safely remove itself as delegate.
So either remove the retain restriction and let A properly retain B.
Or go for a less coupled solution using notifications.
- Let B define a notification, and post on it.
- Let A register as a listener for the notification at creation, and deregister on deallocation.
To be sure to get the server answer, when the first class enters in dealloc (for any reason), it changes the delegate property of the second one to route the answer to the application delegate.
This doesn't sound like a sensible architecture to me. Juggling delegates in the way that you are shouldn't be necessary. Factor out the code that communicates to the server to its own class that persists for as long as you need it to. Don't spread your networking code throughout your app in objects that are coming and going all the time and don't treat your app delegate as a catch all whenever you need something available in more than one place.
精彩评论