5

Sto aggiungendo un CAKeyframeAnimation allo strato di un ImageView per rappresentare l'animazione di un'immagine:La rimozione CAKeyframeAnimation non rilascia la memoria

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"]; 
animation.values = arrayOfImages; 
[animation setRemovedOnCompletion:YES]; 
animation.delegate = self; 
[animation setValue:delegate forKey:@"AnimatedImageViewDelegate"]; 
animation.repeatCount = repeatCount; 
animation.fillMode = kCAFillModeForwards; 
animation.calculationMode = kCAAnimationDiscrete; 
[animation setValue:animationName forKey:@"name"]; 

Quando voglio avviare l'animazione che io chiamo:

animation.duration = duration; 
[self.layer addAnimation:animation forKey:animationName]; 
[self.layer setContents:[animation.values lastObject]]; 

Al termine dell'animazione, voglio rimuoverlo completamente e rilasciare la sua memoria.

[self.layer removeAllAnimations];  
[self.layer removeAnimationForKey:animationName]; 

Facendo questo, e l'utilizzo di strumenti-Activity Monitor, la memoria non è relased a meno che vi liberi l'ImageView completa.

Come posso liberare la memoria dell'animazione senza distruggere UIImageView ???

+0

si può provare a portarlo in autoreleasepool – SAKrisT

risposta

0

Si sta utilizzando il metodo di convenienza per creare un'istanza dell'oggetto. Quindi non avrai il controllo su quando l'oggetto verrà effettivamente rilasciato. Per avere il controllo su quello, è necessario alloc l'oggetto e dealloc da soli:

creare l'istanza:

CAKeyframeAnimation *animation = [[CAKeyframeAnimation alloc] init]; 

Poi, dopo l'animazione finito chiamata dopo le linee Rimuovere:

[animation release]; 
+0

'[CAKeyframeAnimazione animazioneWithKeyPath:]' restituisce un oggetto autoreleased (come da convenzione di denominazione) e non sembra conservarlo (almeno non lo fa nel codice che ha presentato) quindi dovrebbe andare bene. Fare 'alloc/release' invece non lo cambierà. In effetti, dal suo codice direi che tutto va assolutamente bene, quindi il problema deve essere altrove. – DarkDust

+0

Vero, eccetto che non ha alcun controllo quando viene rilasciato quando è autoreleased. Sembra che sia stato autorizzato automaticamente quando la vista viene distrutta, quindi sembra almeno qualcosa che vale la pena provare. –

+0

Anche facendo alloc/init e release dell'animazione, la memoria non diminuisce quando utilizzo Activity Monitor. Quindi, nessuna differenza in termini di memoria utilizzando autorelease o release. Se commento la riga animation.values ​​= arrayOfImages; l'animazione non viene mostrata e la memoria non aumenta, quindi il mio problema è che quando termina l'animazione la memoria non viene rilasciata a meno che non rilasci ImageView. – nano

0

Prima di tutto, se questo è un progetto iOS 5, ARC dovrebbe gestire le tue uscite per te - il che è davvero bello!

Ora - Ho usato molte animazioni nel mio progetto e ho notato raffiche simili nell'heap. La mia ipotesi è che la CA memorizzi molto di ciò che è animato internamente. Per confermare questi elementi sono effettivamente autoreleased Mi consiglia la creazione di un banco di prova per le allocazioni o perdite con lo strumento strumenti e procedere come segue:

  1. Determinare una situazione in cui si desidera attivare e l'animazione.
  2. Contrassegna l'heap al termine dell'animazione.
  3. Attiva qualcosa che ti porterà in un'altra vista dove gli oggetti avrebbero dovuto essere rimossi.
  4. Ripetere il processo nei passaggi 1-2-3 tutte le volte che si desidera. Normalmente lo faccio circa 10 volte o giù di lì.

Questo è tutto .. fondamentalmente animato - contrassegno - annulla - animato - contrassegna. Dovresti vedere le istantanee dell'heap in diminuzione a 0 o quasi a 0 se CoreAnimation sta autoreleggiando correttamente gli oggetti!

Per ulteriori informazioni sulle modalità di test come questo dare un'occhiata a questo articolo:

http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

+0

Grazie per la risposta. Diminuisce a quasi 0 una volta terminata l'animazione, ma solo se rilascio ImageView. Senza rilasciarlo, le crescite di heap sono piuttosto elevate (da 40 KB a 800 KB ogni volta). Ciò significa che CoreAnimation non si sblocca quando finisce. – nano

0

Ho lo stesso problema sulla memoria con CAKeyframeAnimation quando valori impostati = array di immagini. E vedo che il problema che ottengo è che le immagini sono integrate da [UIImage imagewithname:] che viene memorizzato nella memoria cache per impostazione predefinita. Quindi la mia soluzione è cambiare per usare [UIImage imageWithContentsOfFile:] Spero che questo utile.