0

私はプロジェクトをテストしています: https://github.com/devindoty/iBooks-Flip-Animation スクリーンショットを撮るときにメモリ割り当てが増えていることに気付きました。

そのアプリケーションをプロファイリングすると、多くのメモリが CALayer renderInContext に割り当てられることがわかります。原因は CGContextDrawImage のようです。しかし、それを解決する方法は?

ここに必要なコードを貼り付けます。

@implementation iBookAnimationViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.layer.contents = (id)[UIImage imageNamed:@"Shelf_Contents@2x.png"].CGImage;

    UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(flip:)];
    [self.view addGestureRecognizer:gesture];
    [gesture release];

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


#pragma mark -
#pragma mark Gesture

- (void)flip:(UIGestureRecognizer*)gesture{

    FlipSideViewController *controller = [[FlipSideViewController alloc] init];
    controller.delegate = (id<FlipSideDelegate>)self;
    [self presentModalViewController:controller animated:YES];
    [controller release];

}


#pragma mark -
#pragma mark Animation Methods

- (CATransform3D)transformWithDegrees:(CGFloat)degrees{

    if (degrees == 0) {
        return CATransform3DIdentity;
    }

    return CATransform3DMakeRotation((M_PI/180)*degrees, 0.0f, 1.0f, 0.0);

}

- (UIImage*)contentsForView:(UIView*)aView{

    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, [[UIScreen mainScreen] scale]);
    [aView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{

    if (flag) {
        [[anim valueForKey:@"ContentsLayer"] removeFromSuperlayer];
        [[UIApplication sharedApplication] endIgnoringInteractionEvents];
    }

}

- (void)animateFromViewController:(UIViewController*)fromController toViewController:(UIViewController*)toController{

    UIImage *image = [self contentsForView:toController.view];

    CALayer *contentsLayer = [CALayer layer];
    contentsLayer.frame = toController.view.bounds;
    contentsLayer.backgroundColor = [UIColor blackColor].CGColor;
    [toController.view.layer addSublayer:contentsLayer];

    CATransformLayer *transformLayer = [CATransformLayer layer];
    transformLayer.frame = contentsLayer.bounds;
    [contentsLayer addSublayer:transformLayer];

    CALayer *backLayer = [CALayer layer];
    backLayer.contents = (id)image.CGImage;
    backLayer.doubleSided = NO;
    backLayer.frame = transformLayer.bounds;
    backLayer.zPosition = 0.0f;
    backLayer.transform = [self transformWithDegrees:180.0f];
    [transformLayer addSublayer:backLayer];

    CALayer *frontLayer = [CALayer layer];
    frontLayer.contents = (id)[self contentsForView:fromController.view].CGImage;
    frontLayer.doubleSided = NO;
    frontLayer.zPosition = FLIP_GAP;
    frontLayer.frame = transformLayer.bounds;
    frontLayer.masksToBounds = NO;
    [transformLayer addSublayer:frontLayer];

    CALayer *sideLayer = [CALayer layer];
    sideLayer.contents = (id)[UIImage imageNamed:@"Wood Tile.png"].CGImage;
    sideLayer.zPosition = FLIP_GAP/2;
    sideLayer.frame = CGRectMake(transformLayer.bounds.origin.x-(FLIP_GAP/2), transformLayer.bounds.origin.y, FLIP_GAP, transformLayer.bounds.size.height);
    sideLayer.transform = [self transformWithDegrees:90.0f];
    [transformLayer addSublayer:sideLayer];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"sublayerTransform"];
    animation.toValue = [NSValue valueWithCATransform3D:[self transformWithDegrees:179.9f]];
    animation.duration = ANIMATION_DURATION;
    animation.fillMode = kCAFillModeForwards;
    animation.removedOnCompletion = NO;
    animation.delegate = self;
    [animation setValue:contentsLayer forKey:@"ContentsLayer"];
    [transformLayer addAnimation:animation forKey:@"FlipAnimation"];

    [[UIApplication sharedApplication] beginIgnoringInteractionEvents];

}


#pragma mark -
#pragma mark Modal Prentation Methods

- (void)dismissModalViewControllerAnimated:(BOOL)animated{

    UIViewController *modalViewController = self.modalViewController;
    [self animateFromViewController:modalViewController toViewController:self];
    [super dismissModalViewControllerAnimated:NO];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:YES];


}

- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated{

    [super presentModalViewController:modalViewController animated:NO];
    [self animateFromViewController:self toViewController:modalViewController];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];

}


#pragma mark -
#pragma mark FlipSideDelegate

- (void)dismissFlipSideViewController:(FlipSideViewController*)controller{

    [self dismissModalViewControllerAnimated:YES];

}


#pragma mark -
#pragma mark Memory Management

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
}

- (void)dealloc {
    [super dealloc];
}

@end
4

1 に答える 1

0

「Memory Leaks」ツールを備えた Instruments を使用して、正確なユースケースを実行してみてください。それはあなたに決定的な証拠を示している可能性があり、追跡するのは難しい場合があります. また、ヒープ分析に関するbbumの優れたリンクを常にお勧めしています(これにより、過去に私のベーコンが救われました)。http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

于 2012-04-06T10:58:27.517 に答える