it-swarm.com.de

Warum ARC den Speicher nach popViewController nicht freigibt

Ich schiebe und stoße ViewController in UINavigationController.

Ich verfolge den Speicherverbrauch meiner App. Während der neue viewController nach oben drückt, steigt der Speicherverbrauch allmählich an, aber wenn ich denselben ViewController mit [self.navigationController popViewControllerAnimated:NO]; lösche, sinkt der Speicherverbrauch nicht, sondern die Konstante.

Dieser bestimmte viewController kann vom Benutzer viele Male gedrückt und geöffnet werden, was zu einem hohen Speicherbedarf der App im RAM führen kann. 

Was muss ich tun, um meinen Speicherverbrauch zu optimieren?

37
wali naqvi

Wenn Sie einen View-Controller ablehnen (oder einen Popup ausführen), wird er freigegeben, wenn Sie keine starken Zeiger darauf machen (dieser Controller wird vom Navigations-Controller oder dem präsentierenden View-Controller beibehalten), sodass Sie dies normalerweise nicht benötigen (wenn Sie einen Zeiger darauf haben, wenn Sie ihn erstellen, und drücken oder präsentieren).

Es wird veröffentlicht, wenn es keine anderen starken Hinweise darauf gibt

11
Shardul

Versuchen Sie zu vermeiden, starke Eigenschaften für IBOutlets zu verwenden.

Prüfen Sie, ob Sie auf self in einem Block verweisen. Wenn Sie dies tun, besteht die Gefahr, dass Sie die UIViewController-Referenz nach dem Poppen beibehalten. 

Eine ausführlichere Übersicht über die Gründe finden Sie in dieser Antwort: Wie vermeide ich, dass Sie sich selbst in Blöcken erfassen, wenn Sie eine API implementieren?

3
Matthew York

Ich möchte sagen, dass ich meine letzten Tage damit verbracht habe, das Web nach meinem App-Speicherproblem zu durchsuchen. Ich habe zwischen zwei UIViewControllern gewechselt. Einer von ihnen hatte eine Bildlaufansicht, in der alle Unteransichten angezeigt wurden. Es stellte sich heraus, dass dieses UIVC eine neue Bildlaufansicht lädt, ohne dass die vorherige freigegeben wurde. Ich habe mehrere Stunden gebraucht, um es zu realisieren. 

Was ich gemacht habe war:

Suchen Sie nach möglichen Deadlocks in der App und suchen Sie dann nach allen Variablen, die ein starkes Attribut und andere verzweifelte Maßnahmen hatten. Was aber wirklich funktioniert hat, war:

 @IBAction func backBB(sender: UIBarButtonItem) {
    collectionView.removeFromSuperview()
    self.frontView.removeFromSuperview()
    eventsPhotos.removeAll(keepCapacity: false)
    symbolContainerView.removeFromSuperview()
    self.myScrollView.removeFromSuperview()
    dismissViewControllerAnimated(true, completion: {})
}

Ich habe einige Ansichten und Inhalte manuell entfernt. Ich habe es in "Zurück" getan, aber Sie können dies auch mit anderen Methoden wie viewWillDisappear (animiert: Bool) tun.

Nachdem ich dies erstellt hatte, zeigte meine Zuordnungstabelle in den Entwicklerinstrumenten, dass die Speicherzuordnung auf und ab ging ... Und es wurde gelöst ...

2

Wenn der App-Entwurf es dem Benutzer ermöglicht, immer wieder denselben View-Controller zu drücken und zu öffnen, möchten Sie möglicherweise den gleichen View-Controller wiederverwenden und den Inhalt bei jedem Push aktualisieren.

Anstatt sie immer wieder neu zu erstellen und zu zerstören, erstellen Sie einen, richten Sie den Inhalt ein und drücken Sie, wenn er geknallt ist, halten Sie ihn bereit, um wieder angezeigt zu werden. Wenn es das nächste Mal angezeigt werden muss, aktualisieren Sie den Inhalt und drücken Sie es erneut.

2
Dave Wood

Ich denke, Sie erhalten eine Fehlermeldung, wenn Sie versuchen, den View-Controller zu öffnen, da der Navigations-Controller keinen gültigen Verweis auf den View-Controller hat, da er nach dem Drücken freigegeben wurde.

1
codercat

Vergewissern Sie sich, dass Ihr Viewcontroller (A) keinen Verweis auf einen anderen Viewcontroller (B) oder ein Objekt hat, über das er verfügt. In diesem Fall muss sichergestellt werden, dass VC-B nicht auf VC-A verweist. Wenn es einen Bezug zu VC-A hat, machen Sie es zu einer schwachen Eigenschaft. Andernfalls bleibt der VC -Zyklus im Speicher erhalten, auch wenn er geknackt wird.

  • Eine andere Sache ist, zu überprüfen, ob es eine Schließung in Ihrem VC gibt. Überprüfen Sie seinen Körper, wenn er auf eine Eigenschaft oder Methode mit self verweist, und erstellen Sie eine Capture-Liste , um einen Rückhaltezyklus zu vermeiden, da "Verschlüsse sind Referenztypen"
  • Prüfen Sie, ob NSNotification-Beobachter nicht freigegeben werden

  • Führen Sie einen Druckaufruf in der Deinit-Methode aus, um zu überprüfen, ob die Zuordnung freigegeben wird.

Zum besseren Verständnis der Speicherverwaltung:

0
Ammar Mujeeb

Nie den Popover bei der Entlassung.

[menuPopup_ dismissPopoverAnimated:YES];
menuPopup_ = nil;
0
GMJigar