Pergunta

i am writing an app that draws something in a view and it draws based on the devicemotion. But after 4 minutes or so the app crashes and i get this warning:

2014-01-15 17:04:16.605 appName[3427:60b] Received memory warning.

This is the code i have:

  - (void) viewDidLoad
{
    [super viewDidLoad];
    //FIXME: App crash due Memory allocations
        self.motionManager =[[CMMotionManager alloc] init];
    self.motionManager.deviceMotionUpdateInterval = .2;
    [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMDeviceMotion *motion, NSError *error) {
        [self motionMethod:motion];
    }];
}

-(void)motionMethod:(CMDeviceMotion *)deviceMotion
{
    drawImage.image = nil;
    drawImage = [[UIImageView alloc] init];
    drawImage.frame = self.view.frame;

    [self.view addSubview:drawImage];
    float accelerationThreshold = 0.005;
    CMAcceleration userAcceleration = deviceMotion.userAcceleration;
    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsBeginImageContext(CGSizeMake(320, 568));
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.5);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 1, 0, 1);

    float diff = fabs((userAcceleration.x + userAcceleration.y + userAcceleration.z)-oldMove);

    if (fabs(userAcceleration.x) < accelerationThreshold ||
        fabs(userAcceleration.y) < accelerationThreshold ||
        fabs(userAcceleration.z) < accelerationThreshold)
    {
        //vertical top
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 ,
                             self.view.bounds.size.height / 2 + ((self.view.bounds.size.height/100)*2.5));
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width /2,
                                self.view.bounds.size.height -((self.view.bounds.size.height/100)*30));
        //vertical down
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 ,
                             self.view.bounds.size.height / 2 - ((self.view.bounds.size.height /100) *2.5));
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width /2,
                                ((self.view.bounds.size.height/100)*30));

        //horizontal right
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 + ((self.view.bounds.size.width/100)*5) ,
                             self.view.bounds.size.height / 2 );
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width - ((self.view.bounds.size.width/100)*20) ,
                                self.view.bounds.size.height /2  );
        //horizontal left
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 - ((self.view.bounds.size.width/100)*5) ,
                             self.view.bounds.size.height / 2 );
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), ((self.view.bounds.size.width /100)*20),
                                self.view.bounds.size.height /2  );
    }
    else
    {
        float pos = 300 * diff;

        int radius = 100;
        int cX = self.view.bounds.size.width / 2 -50;
        int cY = self.view.bounds.size.height /2 -50;

        CGRect borderRect1 = CGRectMake(cX - pos, cY -pos, radius, radius);
        CGRect borderRect2 = CGRectMake(cX + pos, cY -pos, radius, radius);
        CGRect borderRect3 = CGRectMake(cX , cY + pos, radius, radius);

        CGContextStrokeEllipseInRect(UIGraphicsGetCurrentContext(), borderRect1);
        CGContextStrokeEllipseInRect(UIGraphicsGetCurrentContext(), borderRect2);
        CGContextStrokeEllipseInRect(UIGraphicsGetCurrentContext(), borderRect3);

    }

    oldMove = accelerationThreshold;

    CGContextStrokePath(UIGraphicsGetCurrentContext());

    }

Can someone please help me with this problem? Many thanks.

EDIT: This is my new method without a memory leak:

    -(void)motionMethod:(CMDeviceMotion *)deviceMotion
{
    drawImage.image = nil;
    if (drawImage.image == nil) {
        [drawImage removeFromSuperview];
    }
drawImage = [[UIImageView alloc] init];
drawImage.frame = self.view.frame;
float accelerationThreshold = 0.002;
CMAcceleration userAcceleration = deviceMotion.userAcceleration;

UIGraphicsBeginImageContext(CGSizeMake(self.view.frame.size.width, self.view.frame.size.height));
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 2.5);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0, 1, 0, 1);

float diff = fabs((userAcceleration.x + userAcceleration.y + userAcceleration.z)-oldMove);

if (fabs(userAcceleration.x) < accelerationThreshold ||
    fabs(userAcceleration.y) < accelerationThreshold ||
    fabs(userAcceleration.z) < accelerationThreshold)
{
    //vertical top
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 ,
                         self.view.bounds.size.height / 2 + ((self.view.bounds.size.height/100)*2.5));
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width /2,
                            self.view.bounds.size.height -((self.view.bounds.size.height/100)*30));
    //vertical down
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 ,
                         self.view.bounds.size.height / 2 - ((self.view.bounds.size.height /100) *2.5));
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width /2,
                            ((self.view.bounds.size.height/100)*30));

    //horizontal right
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 + ((self.view.bounds.size.width/100)*5) ,
                         self.view.bounds.size.height / 2 );
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width - ((self.view.bounds.size.width/100)*20) ,
                            self.view.bounds.size.height /2  );
    //horizontal left
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), self.view.bounds.size.width  / 2 - ((self.view.bounds.size.width/100)*5) ,
                         self.view.bounds.size.height / 2 );
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), ((self.view.bounds.size.width /100)*20),
                            self.view.bounds.size.height /2  );
}
else
{
    float pos = 300 * diff;

    int radius = 100;
    int cX = self.view.bounds.size.width / 2 -50;
    int cY = self.view.bounds.size.height /2 -50;

    CGRect borderRect1 = CGRectMake(cX - pos, cY -pos, radius, radius);
    CGRect borderRect2 = CGRectMake(cX + pos, cY -pos, radius, radius);
    CGRect borderRect3 = CGRectMake(cX , cY + pos, radius, radius);

    CGContextStrokeEllipseInRect(UIGraphicsGetCurrentContext(), borderRect1);
    CGContextStrokeEllipseInRect(UIGraphicsGetCurrentContext(), borderRect2);
    CGContextStrokeEllipseInRect(UIGraphicsGetCurrentContext(), borderRect3);

}

oldMove = accelerationThreshold;

CGContextStrokePath(UIGraphicsGetCurrentContext());
[drawImage setFrame:CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height)];
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[self.view addSubview:drawImage];
}

Thanks for all the help.

Foi útil?

Solução

The problem is here:

[self.view addSubview:drawImage];

You add one subview after the other without ever removing one. Take care of removing/releasing unused subviews and your memory issues will disappear.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top