2017-12-10 2 views
3

Gibt es eine "nukleare Option", um die Bilder aus dem Bild-Array freizugeben? Ich möchte die erste Animation1 (ImageSet1) abspielen, dann im Completion Block diese Animation löschen und dann die zweite Animation2 laden und spielen (ImageSet2), und so weiter: Wasche, spüle, wiederhole - du bekommst es :)Wie man Bilder von einem Bild-Array in Swift freigibt

Zuerst definiere ich die Instanzvariablen meiner Viewcontroller:

var animation1: [UIImage] = [] 
var animation2: [UIImage] = [] 
var animation3: [UIImage] = [] 

Dann habe ich eine Animation, Array für jede Animation erstellen:

func createImageArray(total: Int, imagePrefix: String) -> [UIImage]{ 
    var imageArray: [UIImage] = [] 
    for imageCount in 0..<total { 
    let imageName = "\(imagePrefix)-\(imageCount).png" 
    let image = UIImage(named: imageName)! 
    imageArray.append(image) 
    } 
    return imageArray 
    } 

Dann habe ich die belebtes Werte:

func animate(imageView: UIImageView, images: [UIImage]){ 
    imageView.animationImages = images 
    imageView.animationDuration = 1.5 
    imageView.animationRepeatCount = 1 
    imageView.startAnimating() } 

    animation1 = createImageArray(total: 28, imagePrefix: "ImageSet1") 
    animation2 = createImageArray(total: 53, imagePrefix: "ImageSet2") 
    animation3 = createImageArray(total: 25, imagePrefix: "ImageSet3") 

Und schließlich nennen die belebte Funktion

func showAnimation() { 
    UIView.animate(withDuration: 1, animations: { 
     animate(imageView: self.animationView, images: self.animation1) 

     }, completion: { (true) in 

     // Release the Images from the Array 

     }) 
    } 

Ich mochte die Bilder aus dem Bildfeld in dem Abschluss-Block freizugeben, um meinen Speicherbedarf zu senken, aber ich kann das nicht scheine, Arbeit zu bekommen , ich habe versucht, alle vier folgenden Beispiele, aber es gibt keine Auswirkungen auf den Speicherbedarf:

func showAnimation() { 
UIView.animate(withDuration: 1, animations: { 
animate(imageView: self.animationView, images: self.animation1) 

}, completion: { (true) in 

self.animation1 = [] // is this correct? 
self.animationView.image = nil // also doesn't work 
self.animationView.removeFromSuperview() // also doesn't work 
self.animation1 = nil // also doesn't work 

}) 
} 

nach dem Abschluss Block, ich habe die animation1 Array gleich [] eingestellt und es macht die Animation entfernen (kann man nicht sehen Sie es mehr), aber der Speicherabdruck bleibt genau der gleiche (I ha Ich habe auch die anderen drei Möglichkeiten ausprobiert).

Mit den oben genannten, dem Speicher-Footprint ‚Beulen‘ auf jedes Mal, wenn ich die nächste Animation hinzufügen und es verursacht schließlich das O die App

Selbst zu beenden, wenn Sie Viewcontrollers ändern, wird das Array, das immer noch die Bilder in Speicher

Vielen Dank für jede Hilfe :)

+0

Was ist mit self.animation1.removeAll()? –

+0

1. Siehe [hier] (https://stackoverflow.com/a/30829144/5175709) und vielleicht [hier] (https://stackoverflow.com/questions/43333328/how-can-i-deallocate-all- Referenzen-Elemente-von-einem-Array). 2. Wenn die Bilder von einer anderen Zeile in Ihrem Code referenziert und beibehalten werden, muss sie auch von dort freigegeben werden. Zusätzlich sollten Sie 'completion: {(true) in' to 'completion: {[weak self] (true) in' so ändern, dass Sie die Aufnahme von 'self' und die Erstellung von Speicherzyklen vermeiden – Honey

+0

Hi @TusharSharma - danke für Ihre Antwort, ich versucht self.animation1.removeAll() und es gibt immer noch keinen Effekt auf den Speicher (es bleibt gleich) –

Antwort

0

UIImage (genannt:) wird immer das Bild in dem Speicherstapel speichern, wenn es eine Anforderung für mehr Arbeitsspeicher und genügend Zeit freizugeben.

Um Bilder aus dem Speicher freizugeben, sollten Sie den anderen Konstruktor verwenden: UIImage (contentsOfFile:) und die Bilder im Ordner statt des Asset Managers speichern. Vielleicht funktionieren die Daten auch, aber ich bin mir nicht sicher.

Temporäre/Große Ressourcen verbrauchen den Heap, Sie sollten "temp saving" -Methoden wie contentsOfFile verwenden, um sie aus dem Speicher zu löschen.

+1

Ich würde einen externen Ordner namens "Animationen" erstellen, um die Animationen dorthin zu verschieben (außerhalb der Assets - weil Sie keinen Pfad für die Assets erhalten können), und dann verwenden Sie: Bundle.main.path (forResource: ofType:) um die Pfade der Animationsbilder zu laden und UIImage (contentsOfFile: ____) mit dem angegebenen Pfad zu verwenden – unkgd

+1

Sind Sie sicher, dass die Bilder Teil des Projekts sind und Sie die richtigen Namen (ohne Erweiterung) verwenden? Wenn Bundle.main.path (forResource) den Wert nil zurückgibt, bedeutet dies, dass die Bilder nicht geladen werden können. Versuchen Sie, das Projekt vor dem erneuten Kompilieren zu bereinigen. Welcher Parameter ist null? das BündelPfad oder das Bild? – unkgd

+0

Hallo @unkgd - schätzen Sie Ihre Antworten. Ich habe eine neue Frage im Licht Ihrer Kommentare erstellt und wenn Sie hier posten möchten, werde ich Ihre Antwort akzeptieren: https://stackoverflow.com/questions/47744665/how-to-convert-uiimage-to-imagewithcontentsoffile-in -Schalter 3-0 –

Verwandte Themen