How to dispose of old controller in a transition between two views?
I'm trying to create a transition between two views by using their controllers. Problem is, how to dispose of the old control开发者_开发知识库ler once the transition animation is finished? I can't dispose of it before the animation is finished as that leads to a segmentation fault - apparently the animations involved do not increment the retain count on the views they work with.
Only thing I can think of is to provide a method to be called once the animation is finished to release the controller argument. I am hoping someone will have a more elegant solution.
Here is my sample code for a method in my root view controller:
-(void) switchToController:(UIViewController *) controller {
[controller viewWillAppear:YES];
if (self.currentScreenController != nil) {
[self.currentScreenController viewWillDisappear:YES];
[[self.currentScreenController view] removeFromSuperview];
}
[self.view addSubview:[controller view]];
if (self.currentScreenController != nil) {
[self.currentScreenController viewDidDisappear:YES];
}
self.currentScreenController = controller;
[controller viewDidAppear:YES];
//[controller release]; // <- releasing now will cause errors as subsequent animations reference this controller's view
...
// animations start now
[Edit] Well, I can't seem to be allowed to release the controller even after the animation is finished for some unexplained reason. I schedule an NSTimer call a few seconds after the animation completes, I check that the retain count is 1 before releasing, and then when I release it I get a crash. Here is the method that is called by the timer to release already unused controllers:
- (void) releaseOldController {
@synchronized(arrayOfOldControllers) {
if (2 < [arrayOfOldControllers count]) {
NSObject * object = [arrayOfOldControllers objectAtIndex:0];
[arrayOfOldControllers removeObjectAtIndex:0];
NSLog(@"releasing object (%@) with retain count(%d)", object, [object retainCount]);
[object release];
}
}
}
Perhaps my strategy is wrong. What I am trying to accomplish is to simulate book page turning. The book has more than 30 pages, I want to dispose of the old page as soon as the transition to the new page is finished to release memory. So when the user turns to a new page, a new controller with a new view is created and added to the root controller with a fade animation transition of about 1/2 sec. As soon as the animation is finished I want to release the previous page view as only the new page view is visible. This way the root controller view has at most 2 subviews at any one time, and usually only 1 -- the current page viewed, after the transition is complete. This should not be so hard to do, but I don't understand why I am getting an error when releasing a controller when it's no longer in use.
[Update] This question is wrong -- the problem is somewhere else and has nothing to do with controller or view. The code above is correct.
Providing an animation finished callback method will certainly work, but it's a little annoying.
A nicer technique available to you: if you're targetting iOS4 and onwards only, you can use animation blocks -- please see iPhone UIView Animation Best Practice -- in particular, the completion:
bit allows you to specify what happens at the end of the animation, without having to define a new callback method in the usual way.
If you are trying to simulate the page turning I would load all my controllers in to NSMutableArray and use it as my page guide. You can release all the UIViewControllers after adding them to the array, and then you will be able still have access to them whenever you want to go back.
精彩评论