2009-11-23 9 views
5

Sto sviluppando un'applicazione per un iPhone e ho trovato che il codice seguente sta causando l'incremento dell'allocazione di memoria.Istanze ImageIO initImageJPEG che vengono allocate e mai rilasciate

-(UIImage *)createRecipeCardImage:(Process *)objectTBD atIndex:(int)indx 
{ 

[objectTBD retain]; 

// bringing the image for the background 
UIImage *rCard = [UIImage imageNamed:@"card_bg.png"]; 
CGRect frame = CGRectMake(00.0f, 80.0f, 330.0f, 330.0f); 

// creating he UIImage view to contain the recipe's data 
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; 
imageView.image = rCard; 

[rCard release]; 
imageView.userInteractionEnabled = YES; 


float titleLabelWidth = 150.0; 
float leftGutter = 5.0; 
float titleYPos = 25.0; 
float space = 3.0; 
float leftYPos = 0; 

// locating Title label 
float currentHeight = [self calculateHeightOfTextFromWidth:objectTBD.Title :titleFont :titleLabelWidth :UILineBreakModeWordWrap]; 
UILabel *cardTitle = [[UILabel alloc]initWithFrame:CGRectMake(leftGutter, titleYPos, titleLabelWidth, currentHeight)]; 
cardTitle.lineBreakMode = UILineBreakModeWordWrap; 
cardTitle.numberOfLines = 0; 
cardTitle.font = titleFont; 
cardTitle.text = objectTBD.Title; 
cardTitle.backgroundColor = [UIColor clearColor]; 
[imageView addSubview:cardTitle]; 

[cardTitle release]; 

leftYPos = titleYPos + currentHeight + space; 

// locating brown line 
UIView *brownLine = [[UIView alloc] initWithFrame:CGRectMake(5.0, leftYPos, 150.0, 2.0)]; 
brownLine.backgroundColor = [UIColor colorWithRed:0.647 green:0.341 blue:0.122 alpha:1.0]; 
[imageView addSubview:brownLine]; 

[brownLine release]; 

leftYPos = leftYPos + 2 + space + space + space; 

// creating the imageView to place the image 
UIImageView *processPhoto = [[UIImageView alloc] initWithFrame:CGRectMake(leftGutter, leftYPos, 150, 150)]; 


if((uniqueIndex == indx) && (uniqueImg.imageData != nil)) 
{ 

    if([uniqueImg.rcpIden isEqualToString:objectTBD.iden]) 
    { 
     objectTBD.imageData = [NSString stringWithFormat:@"%@", uniqueImg.imageData]; 
     [recipesFound replaceObjectAtIndex:indx withObject:objectTBD]; 


     NSData * imageData = [NSData dataFromBase64String:objectTBD.imageData]; 
     UIImage *rcpImage = [[UIImage alloc] initWithData:imageData]; 
     [imageData release]; 
     processPhoto.image = rcpImage; 
     [rcpImage release]; 

    } 


} 
else if(objectTBD.imageData != nil) 
{ 

    NSData * imageData = [NSData dataFromBase64String:objectTBD.imageData]; 
    UIImage *rcpImage = [[UIImage alloc] initWithData:imageData]; 
    processPhoto.image = rcpImage; 
    [rcpImage release]; 
    [decodedBigImageDataPointers addObject:imageData]; 

} 
else 
{ 
    UIImage * rcpImage = [UIImage imageNamed:@"default_recipe_img.png"]; 
    processPhoto.image = rcpImage; 
    [rcpImage release]; 
} 

NSlog(@" Process Photo Retain Count %i", [processPhoto retainCount]); // this prints a 1 
[imageView addSubview:processPhoto]; 

NSlog(@" Process Photo Retain Count %i", [processPhoto retainCount]); // this prints a 2!!!! 
//[processPhoto release]; // this line causes an error :( 



// converting the UIImageView into a UIImage 
UIGraphicsBeginImageContext(imageView.bounds.size); 
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

[objectTBD release]; 

for(UIView *eachSubview in imageView.subviews) 
{ 
    [eachSubview removeFromSuperview]; 
    NSLog(@"each subview retainCount %i despues", [eachSubview retainCount]); 
    // here I find that the processPhoto view has a retain count of 2 (all other views have their retain count in 1) 
} 

return viewImage; 

} 

Quando ho controllato l'assegnazione degli oggetti degli strumenti, ho scoperto che "GeneralBlock-9216" cresceva.

rottura lungo la fila ho trovato che ogni volta che chiamo questo codice, un'istanza di:

2 0x5083800 00:18.534 ImageIO initImageJPEG 

viene allocato. Selezionando lo stack di chiamate, viene evidenziata la seguente riga:

UIImage * objImage = [UIImage imageWithData:imageData]; 

Qualsiasi aiuto per trovare l'errore?

+0

Ho lo stesso problema e sarei interessato alla soluzione. – Kamchatka

risposta

1

Penso che stiate vedendo immagini di UIImage cacheing. Lì usato c'era un metodo come initWithData:cache che ti consente di disattivare la cache. Ora penso che il sistema memorizzi automaticamente le immagini automaticamente dietro le quinte anche dopo aver disallocato le istanze specifiche.

Non credo che sia un errore da parte vostra. Penso che sia il sistema che mantiene i dati nel sottosistema OpenGl. A meno che non causi una perdita importante, non penso che sia un problema.

+0

Ciao Techzen !!, grazie mille per la risposta, ma questo problema mi causa un sacco di allocazione di memoria perché, questo metodo è chiamato da un delegato flowCover, è quello che costruisce le carte. Ho notato che non solo UIImage viene assegnato ogni volta, anche tutte le UIlabels che ho aggiunto come subviews a imageView. :( – alex

+0

Potrebbe essere necessario vedere più codice. Questo codice non perderà da solo, tuttavia, se lo chiami ripetutamente, mangerà molta memoria perché inizializza un nuovo UIImageView ogni volta che viene chiamato e la vista dell'immagine conserva l'immagine. Se chiami questo codice ripetutamente, otterrai una grande quantità di visualizzazioni complete con le loro immagini e tutte le sottoview.Invece, dovresti inizializzare una o due immagini e quindi scambiare le immagini secondo necessità .. – TechZen

+0

Grazie TechZen !! I ho apportato alcune modifiche al codice utilizzando i tuoi consigli e anche quello pubblicato da KatokichiSoft ma ho avuto lo stesso problema :( Ho aggiornato il codice con l'ultima versione. Ormai con il for alla fine l'allocazione UIlabels non sta accadendo, ma l'assegnazione dell'immagine continua a comparire :(. – alex

2

Come diceva TechZen, i metodi imageWithXXX: nascondono l'immagine all'interno di essi mentre si esegue il programma (sebbene si rilascino le istanze dopo l'uso). Raccomando i set di API initWithXXX: e release anziché imageWithXXX:.

Bene, se si incorpora un registro di debug sul proprio codice sorgente, controllare quante volte viene chiamato e controllare il conteggio delle istanze.

Per quanto posso spiegare, questo è tutto. Spero che risolverai il problema.

+0

Grazie mille KatokichiSoft, ho usato la tua raccomandazione e ho lo stesso problema, Ho pubblicato l'ultima versione del mio codice, forse qualcosa è mancato. Negli strumenti l'output è lo stesso, appare lo stesso tipo di oggetto :(. – alex

+0

Ho riscontrato lo stesso problema, ma quelle immagini provengono da initWithContentsOfFile:. – AechoLiu

2

Qualcuno ha una risposta per questo? Mi sta distruggendo cercando di capire perché questa immagine continua a persistere. Ho provato ogni soluzione.

La situazione:

immagini vengono scaricati e memorizzati sul dispositivo, poi caricato con imageWithContentsOfFile (o anche initWithContentsOfFile, che non aiuta neanche). Quando la vista scompare, le immagini non lo fanno, ma non si presentano come perdite, sono solo questo initImageJPEG Malloc 9.00 KB che non scompare mai e continua a crescere.

UPDATE: Credo di aver capito questo: Verificare che dealloc'd tutto è in realtà sempre quando si sta liberando quali che siano i genitori (e/o nonni) ed ecc delle immagini sono. Se i genitori non vengono deallocati, non rilasciano mai le immagini dei loro figli, e qualunque dato sia contenuto in quelle immagini rimane intatto. Quindi controlla il conteggio dei conteggi degli oggetti parent e assicurati che tutto vada via fino a quando non rilasci la vista in alto.

Un buon modo per verificare questo è di mettere NSLogs nei metodi dealloc delle classi personalizzate. Se non si presentano mai, quell'oggetto non sta andando via, anche se il riferimento ad esso potrebbe, e questo (e qualunque sia la sua sottoview e proprietà) non scomparirà mai. Nel caso delle immagini, ciò significa un'allocazione piuttosto considerevole ogni volta che l'oggetto viene generato e mai deallocato.Potrebbe non apparire in perdite, soprattutto se il genitore dell'oggetto più in alto che stai pensando di rilasciare, ma in realtà non è persistente e non si distacca da sé.

Spero che questo aiuti. Sarà utile dedicare un po 'di tempo a leggere il codice con un pettine a denti stretti per assicurarti di allocare e rilasciare le cose correttamente. (Cerca "alloc]", inizia nella parte superiore del file e scendi per assicurarti di essere rilasciato e che la versione non sia all'interno di if() o qualcosa del genere.)

Anche , eseguire "Build and Analyze" potrebbe bloccare la macchina per un po ', ma i suoi risultati possono essere davvero utili.

Buona fortuna!

+0

Credo di aver capito questo. secondo: –

+0

quali sono stati i tuoi risultati? Penso di avere lo stesso problema. – Slee

Problemi correlati