2013-10-11 3 views
0

Je constate une augmentation importante de l'utilisation de la mémoire (de 39 Mo à 186 Mo sur iPad) avec l'exécution de l'instruction "CGContextFillRect" dans mon code ci-dessous. Y a-t-il quelque chose qui ne va pas ici.Pic de mémoire soudaine avec CGContextFillRect

Mon application finit par tomber en panne. PS: De manière surprenante, le pic de mémoire est visible sur les iPads de 3ème et 4ème génération et non sur les iPad de 2ème génération.

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self setBackgroundColor:[UIColor clearColor]]; 
    } 
    return self; 
} 


- (id)initWithFrame:(CGRect)iFrame andHollowCircles:(NSArray *)iCircles { 

    self = [super initWithFrame:iFrame]; 
    if (self) { 
     [self setBackgroundColor:[UIColor clearColor]]; 
     self.circleViews = iCircles; 
    } 
    return self; 
} 


- (void)drawHollowPoint:(CGPoint)iHollowPoint withRadius:(NSNumber *)iRadius { 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    CGContextSetLineWidth(currentContext, self.circleRadius.floatValue); 
    [[UIColor whiteColor] setFill]; 
    CGContextAddArc(currentContext, iHollowPoint.x, iHollowPoint.y, iRadius.floatValue, 0, M_PI * 2, YES); 
    CGContextFillPath(currentContext); 
} 


- (void)drawRect:(CGRect)rect { 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(currentContext); 
    CGRect aRect = [self.superview bounds]; 
    [[UIColor whiteColor]setFill]; 
    CGContextFillRect(currentContext, aRect); 

    CGContextSaveGState(currentContext); 
    [[UIColor blackColor]setFill]; 
    CGContextFillRect(currentContext, aRect); 
    CGContextRestoreGState(currentContext); 

    for (MyCircleView *circleView in self.circleViews) { 
     [self drawHollowPoint:circleView.center withRadius:circleView.circleRadius]; 
    } 

    CGContextTranslateCTM(currentContext, 0, self.bounds.size.height); 
    CGContextScaleCTM(currentContext, 1.0, -1.0); 
    CGContextSaveGState(currentContext); 
} 

Répondre

1

Ce code n'a pas vraiment de sens; Je suppose que vous avez supprimé des parties de celui-ci? Vous créez un masque alpha vide et ensuite le jeter.

Si le code ci-dessus est vraiment ce que vous faites, vous n'avez vraiment besoin de rien dessiner. Vous pouvez simplement créer une zone de mémoire de 12 Mo et la remplir en répétant 1 0 0 0 (noir opaque en ARGB), puis créer une image à partir de cela. Mais je suppose que vous faites plus que cela.

Vous avez probablement cette vue configurée avec contentScaleFactor définie pour correspondre à la scale de UIScreen, et cette vue est très grande. Les iPads de 3ème et 4ème génération disposent d'un écran Retina, donc l'échelle est 2, et la mémoire nécessaire pour dessiner une vue est 4 fois plus grande. Cela dit, vous ne devriez vous attendre à environ 12 Mo pour contenir une image en plein écran (2048 * 1536 * 4). Le fait que vous voyez 10x qui suggère quelque chose de plus se passe, mais je soupçonne que c'est toujours lié à peut-être tirer trop de copies.

Si possible, vous pouvez réduire la graduation à 1 pour que la rétine et la rétine se comportent de la même manière.


EDIT:

Votre code modifié est très différent de votre code d'origine. Il n'y a aucune tentative de faire une image dans ce code. Je l'ai testé du mieux que je peux, et je ne vois aucun pic de mémoire surprenant. Mais il y a plusieurs bizarreries:

  • Vous n'êtes pas correctement équilibrage CGContextSaveGState avec CGContextRestoreGState. Cela pourrait causer un problème de mémoire. Pourquoi dessinez-vous le rect tout en blanc et tout en noir? Le rect est [self.superview bounds]. C'est dans le mauvais espace de coordonnées. Vous devriez presque certainement dire [self bounds].
  • Pourquoi inversez-vous le contexte avant de revenir à drawRect, puis enregistrez le contexte? Cela n'a aucun sens.

Je suppose que votre drawRect: ressemblerait à ceci:

- (void)drawRect:(CGRect)rect { 
    [[UIColor blackColor] setFill]; 
    UIRectFill(rect); // You're only responsible for drawing the area given in `rect` 

    for (CircleView *circleView in self.circleViews) { 
    [self drawHollowPoint:circleView.center withRadius:circleView.circleRadius]; 
    } 
} 
+0

Oui Rob. Vous avez raison de dire que je fais plus que ce que j'ai collé plus tôt. J'ai mis mon code exact. Ce que j'essaie de faire, c'est dessiner des cercles creux à mon avis. J'ai essayé avec BezierPaths mais quand les cercles se croisent, il se comporte bizarrement avec la règle de remplissage pair/impair. Pourriez-vous s'il vous plaît m'aider à résoudre ce problème de mémoire avec les appareils de la rétine. – Abhinav

Questions connexes