J'ai créé une application de test assez simple. Il comprend 3 contrôleurs de vue. Le contrôleur de vue principal a une vue de table, qui utilise des cellules personnalisées. Les deux autres contrôleurs de vue sont accessibles via le contrôleur de vue principal, chacun ont des vues de collection et peuvent revenir au contrôleur de vue principal.

Voici le problème de la mémoire. Chaque fois que je clique sur l'une des cellules des 3 contrôleurs de vue, l'utilisation de la mémoire augmente. J'ai exécuté l'application en utilisant le modèle de profilage «Leaks» et je n'ai trouvé aucune fuite. Également utilisé le modèle de profilage «Allocations», vérifié 2 des contrôleurs de vue (enregistré les décomptes de références), et tous les décomptes de références stockés sous mon programme ont été libérés.

Je n'ai pas pu utiliser le graphe de mémoire de débogage car il n'arrête pas de planter Xcode ...

Contrôleur de vue principale

import UIKit

class TableViewController: UITableViewController, UISearchBarDelegate {

    @IBOutlet weak var searchForTool: UISearchBar!
    @IBOutlet weak var toolTable: UITableView!

    var searchActive : Bool = false
    var data = ["  Alphabetical", "  Numerical"]
    var identities = ["A", "B"]

    override func viewDidLoad() {
        super.viewDidLoad()

        toolTable.delegate = self
        toolTable.dataSource = self
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell

        cell.toolLabel.text = data[indexPath.row]
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let vcName = identities[indexPath.row]
        let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
        self.navigationController?.pushViewController(viewController!, animated: true)
    }
}

Un des autres contrôleurs de vue (tous deux identiques)

import UIKit

class AlphabeticalViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!

    var labelArray = [String]()
    var identities = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        labelArray = ["Main", "Definitions", "Steps", "References", "Other"]

        identities = ["C", "B", "B", "D", "E"]

        self.navigationController?.setNavigationBarHidden(true, animated: false)

        collectionView.delegate = self
        collectionView.dataSource = self

    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return labelArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

        let myLabel = cell.viewWithTag(1) as! UILabel

        myLabel.text = labelArray[indexPath.row]

        return cell
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        let vcName = identities[indexPath.row]
        let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
        self.navigationController?.pushViewController(viewController!, animated: true)

    }

}

Classe de cellule personnalisée

import UIKit

class CustomCell: UITableViewCell {

    @IBOutlet weak var toolLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Je fournirai toute autre image si nécessaire. Toute aide serait grandement appréciée.

Informations que j'ai obtenues à l'aide de l'outil d'allocation. Possible Memory Leak Le code commenté est juste une fonction de recherche dont je n'ai pas besoin de guichet automatique.

Storyboard

3
Slavic the Slavic 20 avril 2017 à 22:46

3 réponses

Meilleure réponse

Tout d'abord, je tiens à remercier @totiG d'avoir souligné que le problème pourrait provenir du contrôleur de navigation, et il avait raison.

Il y a d'autres problèmes de mémoire plus petits, mais le plus gros était de loin lié à ma navigation. J'ai continué à pousser les contrôleurs sur la pile de navigation, sans les faire sauter.

Voici le code de ma solution finale.

J'ai remplacé:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let vcName = identities[indexPath.row]
    let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
    self.navigationController?.pushViewController(viewController!, animated: true)

}

Avec:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if indexPath.row == 0 {
        if let navController = self.navigationController {
            for controller in navController.viewControllers {
                if controller is TableViewController {
                    navController.popToViewController(controller, animated: true)
                }
            }
        }
    } else {

        let vcName = identities[indexPath.row]
        let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
        self.navigationController?.pushViewController(viewController!, animated: true)
    }
}

Alors maintenant, au lieu de passer d'un contrôleur à un autre sans faire sortir aucun d'entre eux de la pile, je fais apparaître tous les contrôleurs précédents jusqu'au 'TableViewController' lorsque vous cliquez sur 'Main'.

0
Slavic the Slavic 23 mai 2017 à 16:51

Vous avez un problème avec votre tableView et votre vue de collection. regardez IBOutlets votre tableView name est toolTable

@IBOutlet weak var toolTable: UITableView!

Mais dans votre source de données pour la tableView, vous accédez à la mauvaise tableView

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // this is the wrong tableView
    /*
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
    */
    // you should use the tableview which you have declared 
    let cell = toolTable.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
    cell.toolLabel.text = data[indexPath.row]
    return cell
}

Vous rencontrez également le même problème avec vos CollectionViewControllers.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    //accessing wrong collectionView
    /*
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
    */
    // here you have to use self because your have named your collectionView the same as collectionView
    let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
    let myLabel = cell.viewWithTag(1) as! UILabel

    myLabel.text = labelArray[indexPath.row]

    return cell
}

Remarque: votre TableViewController et CollectionViewController sont déjà des contrôleurs. vous vous demandez pourquoi vous avez une autre vue de table et de collection IBOutlets. Utilisez-en un à la fois

0
Khalid Afridi 20 avril 2017 à 22:31

Le problème semble être à l'intérieur du CustomCell, peut-être que certaines ressources n'ont pas été initialisées. Avez-vous du code à l'intérieur de awakeFromNib() ou setSelected(...)?

0
A. Barone 20 avril 2017 à 21:54