iPad crash while animating the background image

I created a view controller with a png image and a long jpg background (it's width is twice the width of the iPad - 2048px). moving the png image makes the background image to move to the left in a seamless manner. see this image for an illustrative reference:

image

When playing with it on the iPad, it crashes anytime I move it more then 3-4 times one after the other. Does anyone has a clue what can be the cause of these crashes? I tried checking for memory leaks and couldn't find one though I'm not sure it's really free of them. The debugger shoots memory overload warning but I dont think there are so many memory consuming assets there. there's a jpg background image of 2048X768 px (about 150 kb) and a png static image of about 90 kb. other then that there are two sounds, one about 200 kb that plays once and one of about 50 kb which runs on each touchmoved event. my implementation code is as follow:

    #import "Page5.h"

    #define kUpdateRate (1.0 / 60.0)
    #define kRightX (1024.0)
    #define kLeftX (0.0)

    @implementation Page5
    @synthesize animationTiny, bg, kMoveX;
    @synthesize narPlayer, fxPlayer, narPath, fxPath;


    - (void)viewDidLoad {

    animationTiny.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"5-tiny-ipad-1" ofType:@"png"]];

    [super viewDidLoad];

    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(flipIntervalEnded) userInfo:nil repeats:NO];
    }

- (void)narPlayPath:(NSString *)path {
        if (narPlayer!=nil) [narPlayer release];
        narPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
        narPlayer.delegate = self;
        [narPlayer play];
    }

    - (void)fxPlayPath:(NSString *)path {
        if (fxPlayer!=nil) [fxPlayer release];
        if ([tmbHDPrefs integerForKey:@"SoundFX"]==YES) {
            fxPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
            fxPlayer.delegate = self;
            if ([narPlayer isPlaying]==YES) {
                fxPlayer.volume = 0.2;
            }
            [fxPlayer play];
        }
    }


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

    - (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];

        // Release any cached data, images, etc that aren't in use.
    }


    - (void)viewDidUnload {
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }

    -(void)flipIntervalEnded {
        timer=nil;
        int trackNumber = 8;
        NSString *narrationString = [NSString stringWithFormat:@"tmbtrack%i_%i",[tmbHDPrefs integerForKey:@"Narration"],trackNumber];
        narPath = [[NSBundle mainBundle] pathForResource:narrationString ofType:@"caf"];
            [self narPlayPath:narPath];     
        narPath=nil;
    }

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
        UITouch *touch = [[event allTouches] anyObject];
        if ([touch view] == animationTiny) {
            if ( [timerFloat isValid]){
                [timerFloat invalidate];
                timerFloat = nil;
            }
        self.kMoveX = 30.0;
            fxPath = [[NSBundle mainBundle] pathForResource:@"fx5-water-swoosh" ofType:@"caf"];
            [self fxPlayPath:fxPath];
            fxPath = nil;   
        timerFloat = [NSTimer scheduledTimerWithTimeInterval:kUpdateRate target:self selector:@selector(scrollView) userInfo:nil repeats:YES];
        }
    }


-(void)scrollView {
        float oldX = self.bg.center.x - self.kMoveX;
        float newX = oldX;

        if (oldX < kLeftX) {
            newX = kRightX;
        }

        self.bg.center = CGPointMake(newX, self.bg.center.y);

        self.kMoveX -= 0.05;

        if (kMoveX <= 0.0) {
            kMoveX = 0.0;
        }    
    }

- (void)dealloc {
        self.animationTiny = nil;
        self.bg = nil;
        self.narPlayer = nil;
        self.fxPlayer = nil;
        self.narPath = nil;
        self.fxPath = nil;
        [super dealloc];
    }


@end

tnx in advance, Uri

Answers


You are in fact only loading the image once, but that's actually quite large for an image. Images once loaded are kept uncompressed in memory. 2048x768 with 4 bytes per pixel = 6.2MB, which might (not sure) need to be duplicated as a texture for the GPU in the underlying rendering pipeline. That's big, but not stupid-huge, depending on what else you're loading.

No guarantees that this is the source of your woes, but try it with no image and see. :)

If that's the problem, look at CATiledLayer, or load it in chunks as you scroll.


Need Your Help

Duplicate Username should not be allowed

backbone.js marionette backbone-views backbone-events backbone-relational

I have created UI for users to create their own username and password. Username and passwords are stored in JSON format.

How do determine if an object is locked (synchronized) so not to block in Java?

java synchronization

I have a process A that contains a table in memory with a set of records (recordA, recordB, etc...)