2010-10-18 3 views
0

Actuellement j'utilise UIView au lieu de UIImageview en raison de la consommation de mémoire dans les images à grande échelle. Le code suivant est le même que celui que j'utilise.Drawrect provoquant des problèmes de mémoire

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextClearRect(context, rect); 
    [myImage drawInRect:rect]; 
} 

-(void) SetImage:(UIImage*) aImage 
{ 
    if(!aImage) 
     return; 

    if(myImage) 
    { 
     [myImage release]; 
     myImage = nil; 
    } 

    myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain]; 
    [self setNeedsDisplay]; 
} 

Cela provoque maintenant fuite de mémoire de 8 Mo (vérifié avec l'instrument) à chaque fois lorsqu'Update et définissez la même image à nouveau. si je commente

[self setNeedsDisplay]; 

Il n'y a pas de fuite. Quelqu'un peut-il m'aider ici si je fais quelque chose de mal. OU quelqu'un peut-il m'aider à sous-classer UIImageview pour gérer une image à grande échelle.

// Calling functions 
    -(void) FitToCardStart 
    { 
     UIImage* temp = ScaleImage([iImageBgView GetImage]); 
     [iImageBgView SetImage:temp]; 
     [temp release]; 
     temp = nil; 

    } 

// ScaleImage 

UIImage* ScaleImage(UIImage* image) 
{ 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

    int kMaxResolution = 1800; 

    CGImageRef imgRef = image.CGImage; 
    CGFloat width = CGImageGetWidth(imgRef); 
    CGFloat height = CGImageGetHeight(imgRef); 

    CGAffineTransform transform = CGAffineTransformIdentity; 

    CGRect bounds = CGRectMake(0, 0, width, height); 

    if (width < kMaxResolution || height < kMaxResolution) 
    { 
     CGFloat ratio = width/height; 
     if (ratio > 1) 
     { 
      bounds.size.width = kMaxResolution; 
      bounds.size.height = bounds.size.width/ratio; 
     } 
     else 
     { 
      bounds.size.height = kMaxResolution;  
      bounds.size.width = bounds.size.height * ratio; 
     } 
    } 

    CGFloat scaleRatio = bounds.size.width/width; 
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); 

    UIImageOrientation orient = image.imageOrientation; 

    switch(orient) 
    { 

     case UIImageOrientationUp: //default 
      transform = CGAffineTransformIdentity; 
      break; 

     default: 
      [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; 
    } 

    UIGraphicsBeginImageContext(bounds.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextScaleCTM(context, scaleRatio, -scaleRatio); 
    CGContextTranslateCTM(context, 0, -height); 

    CGContextConcatCTM(context, transform); 
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); 
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); 
    UIImage* temp = [[[UIImage alloc] initWithCGImage:imageCopy.CGImage] retain]; 
    CGImageRelease(imgRef); 
    CGContextRelease(context); 

    [pool release]; 

    return temp; 
} 

Merci,

Sagar

Répondre

0

Je suggère de ne pas créer une nouvelle image, mais simplement de conserver l'instance aImage.

myImage = [aImage retain]; 

Vous devez absolument en faire une nouvelle instance, vous le faites d'une manière très détournée. La copie serait une bien meilleure alternative.

myImage = [aImage copy]; 
+0

Merci pour la réponse, mais ayant toujours le même problème. –

1
myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain]; 

Il y a conserver redondante dans cette ligne - comme vous l'allocation nouvelle méthode objet UIImage (utilisation + alloc) vous n'avez pas besoin de retenir supplémentaire il.

Modifier: méthode scaleImage a le même problème avec redondance retenir:

// remove extra retain here 
UIImage* temp = [[[UIImage alloc] initWithCGImage:imageCopy.CGImage] retain]; 
// should be 
UIImage* temp = [[UIImage alloc] initWithCGImage:imageCopy.CGImage]; 

Et un commentaire de style de code - il est préférable d'indiquer dans vos noms de méthode quel comportement gestion de la mémoire requise pour les objets retournés - que l'image renvoyée par votre méthode nom de la méthode doit être libéré devrait contenir quelque chose de « nouveau », « alloc », « copie », « créer » ...

1

votre problème est cette ligne:

myImage = [[[UIImage alloc]initWithCGImage:aImage.CGImage] retain]; 

alloc vous donne déjà un nombre de retenue de 1, avec le retain supplémentaire vous vous retrouvez avec un nombre de retenue de 2 qui est trop élevé. Retirez le retain et tout ira bien.

+0

Merci DarkDust pour la réponse J'ai fait avec cela mais j'ai toujours le même problème. –

+0

@Sagar, pouvez-vous également poster du code où vous créez une méthodeImageImage et SetImage? – Vladimir

+0

@Vladimir J'ai mis à jour mon message avec du code. –

Questions connexes