I have built an iOS app that is almost done, however, I have recently experienced that it crashes after while due to "Memory pressure". So I started profiling the memory allocations in Instruments and sure, the app does use quite a lot of memory and it only seems to increase during usage.
However, relatively new to Instruments memory allocation I am not quite able to decipher where 52 % of the allocations are made, as seen in the screenshot below:
It has obviously got something to do with Core Animation, but what exactly is hard for me to determine, so I thought that some clever minds out there might know the answer to that.
Breadcrumb:
My app uses custom segues, when moving between view controllers, where a lot of animation is taking place. Here is an example:
@interface AreaToKeyFiguresSegue : UIStoryboardSegue
@end
...
@implementation AreaToKeyFiguresSegue
- (void)perform
{
[self sourceControllerOut];
}
- (void)sourceControllerOut
{
AreaChooserViewController *sourceViewController = (AreaChooserViewController *) [self sourceViewController];
KeyFigureViewController *destinationController = (KeyFigureViewController *) [self destinationViewController];
double ratio = 22.0/sourceViewController.titleLabel.font.pointSize;
sourceViewController.titleLabel.adjustsFontSizeToFitWidth = YES;
[UIView animateWithDuration:TRANSITION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
// Animate areaChooser
sourceViewController.areaChooserScrollView.alpha = 0;
sourceViewController.areaScrollViewVerticalSpaceConstraint.constant = -300;
sourceViewController.backButtonVerticalConstraint.constant = 20;
sourceViewController.backButton.transform = CGAffineTransformScale(sourceViewController.backButton.transform, ratio, ratio);
sourceViewController.backButton.titleLabel.textColor = [UIColor redKombitColor];
sourceViewController.backArrowPlaceholderVerticalConstraint.constant = 14;
sourceViewController.backArrowPlaceholder.alpha = 1;
sourceViewController.areaLabelVerticalConstraint.constant = 50;
sourceViewController.areaLabel.alpha = 1;
[sourceViewController.view layoutIfNeeded];
} completion:^(BOOL finished) {
[destinationController view]; // Make sure destionation view is initialized before animating it
[sourceViewController.navigationController pushViewController:destinationController animated:NO]; // Push new viewController without animating it
[self destinationControllerIn]; // Now animate destination controller
}];
}
- (void)destinationControllerIn
{
AreaChooserViewController *sourceViewController = (AreaChooserViewController *) [self sourceViewController];
KeyFigureViewController *destinationController = (KeyFigureViewController *) [self destinationViewController];
destinationController.keyFigureTableViewVerticalConstraint.constant = 600;
destinationController.keyFigureTableView.alpha = 0.0;
destinationController.allFavoritesSegmentedControl.alpha = 0.0;
[destinationController.view layoutIfNeeded];
[sourceViewController.segueProgress setHidden:YES];
}
@end
And whenever a view controller is to be popped, I simply do the reverse thing:
- (IBAction)goBack:(id)sender
{
[UIView animateWithDuration:TRANSITION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.keyFigureTableView setAlpha:0];
self.keyFigureTableViewVerticalConstraint.constant = 700;
[self.allFavoritesSegmentedControl setAlpha:0];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[self.navigationController popViewControllerAnimated:NO]; // Pop viewController without animating it
}];
}
Edit:
Most of the memory allocation takes place when pushing a view controller, even if it has already been displayed before. I.e. going from
A -> B -> C
B <- C
B -> C
where "->" = push and "<-" = pop, each "->" allocates more memory and "<-" never releases any.
Further details
I have no zombies and no leaks according to Instruments. Static analysis also gives nothing. My app just keeps allocating memory until it finally crashes.
Around 70 % of my memory allocation happens in the following call stack, which has nothing to do with my code (inverted call tree):
