内存使用量不断增加

时间:2017-04-20 19:46:19

标签: ios swift memory memory-leaks

我创建了一个非常简单的测试应用程序。它包括3个视图控制器。主视图控制器具有使用自定义单元格的表视图。另外两个视图控制器可以通过主视图控制器访问,每个都有集合视图,可以返回主视图控制器。

这是内存问题。每当我点击3个视图控制器中的任何一个单元时,内存使用量就会增加。我在使用'泄漏'分析模板时运行应用程序,发现没有泄漏。还使用了“Allocations”分析模板,检查了2个视图控制器(记录了引用计数),并且发布了我程序中存储的所有引用计数。

我无法使用调试内存图,因为它不断崩溃Xcode ......

主视图控制器

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)
    }
}

其他一个视图控制器(两者都相同)

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)

    }

}

自定义单元格类

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
    }

}

如果需要,我会提供任何其他图片。任何帮助将不胜感激。

我使用分配工具获得的信息。 Possible Memory Leak 注释掉的代码只是一个我不需要atm的搜索功能。

Storyboard

3 个答案:

答案 0 :(得分:0)

问题似乎在CustomCell内部,可能有些资源未被初始化。 你在awakeFromNib()setSelected(...)内有一些代码吗?

答案 1 :(得分:0)

您的tableView和集合视图有问题。查看IBOutlets你的tableView名称是toolTable

@IBOutlet weak var toolTable: UITableView!

但是在tableView的数据源中你正在访问错误的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
}

您的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
}

注意:您的TableViewController和CollectionViewController已经是控制器。想知道为什么你有另一个tableView和集合视图IBOutlets。一次使用一个

答案 2 :(得分:0)

首先,我想赞扬@totiG指出问题可能出在导航控制器上,他是对的。

还有其他较小的内存问题,但迄今为止最大的问题与我的导航问题有关。我一直把控制器推到导航堆栈上,没有弹出它们。

以下是我最终解决方案的代码。

我换了:

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

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

}

使用:

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)
    }
}

所以现在不是从控制器推送到控制器而不是从堆栈中弹出任何一个,而是在点击'Main'时将所有以前的控制器弹出到'TableViewController'。