简体   繁体   English

内存使用量不断增加

[英]Memory usage keeps increasing

I've created a pretty simple test app. 我创建了一个非常简单的测试应用程序。 It includes a 3 view controllers. 它包括3个视图控制器。 The main view controller has a table view, that uses custom cells. 主视图控制器具有一个使用自定义单元格的表视图。 The other two view controllers are able to be accessed through the main view controller, each have collection views, and can go back to the main view controller. 可以通过主视图控制器访问其他两个视图控制器,每个视图控制器都有集合视图,并且可以返回到主视图控制器。

Here is the memory issue. 这是内存问题。 Anytime I click on any of the cells from the 3 view controllers, the memory usage increases. 每当我单击3个视图控制器中的任何一个单元时,内存使用量都会增加。 I ran the app while using the 'Leaks' profiling template and found no leaks. 我在使用“泄漏”分析模板时运行了该应用程序,但没有发现泄漏。 Also used the 'Allocations' profiling template, checked 2 of the view controllers (recorded the reference counts), and all the stored reference counts under my program were released. 还使用了“分配”配置文件模板,检查了2个视图控制器(记录了引用计数),并释放了我程序下所有已存储的引用计数。

I haven't been able to use the Debug Memory Graph as it keeps crashing Xcode... 我一直无法使用Debug Memory Graph,因为它不断使Xcode崩溃...

Main View Controller 主视图控制器

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

One of the other View Controllers (both identical) 其他视图控制器之一(两者相同)

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)

    }

}

Custom Cell Class 自定义单元格类

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
    }

}

I will provide any other images if needed. 如果需要,我将提供其他图像。 Any help would be greatly appreciated. 任何帮助将不胜感激。

Information I got using the allocation tool. 我使用分配工具获得的信息。 可能的内存泄漏 The commented out code is just a search feature that I don't need atm. 注释掉的代码只是我不需要atm的搜索功能。

故事板

The problem seems to be inside the CustomCell , maybe some resources not deinitialized. 问题似乎出在CustomCell内部,也许某些资源未初始化。 Do you have some code inside awakeFromNib() or setSelected(...) ? awakeFromNib()setSelected(...)是否有一些代码?

You have problem with your tableView and collection view. 您的tableView和collection视图有问题。 look at IBOutlets your tableView name is toolTable 看IBOutlets你的tableView名称是toolTable

@IBOutlet weak var toolTable: UITableView!

but inside your datasource for the tableView you're accessing the wrong tableView 但是在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
}

You have the same problem with your CollectionViewControllers as well. 您的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
}

Note: Your TableViewController and CollectionViewController are already Controllers. 注意:您的TableViewController和CollectionViewController已经是Controllers。 wondering why you have another tableView and collection view IBOutlets. 想知道为什么还要使用另一个tableView和collection视图IBOutlets。 Use one at a time 一次使用一个

Firstly, I want to give credit to @totiG for pointing out that the problem could be with the navigation controller, and he was right. 首先,我要感谢@totiG指出问题可能出在导航控制器上,他是对的。

There are other smaller memory issues, but the biggest by far had to do with my navigation. 还有其他较小的内存问题,但迄今为止最大的问题与我的导航有关。 I kept pushing controllers onto the navigation stack, without popping them. 我一直将控制器推入导航堆栈,而没有弹出它们。

Here is the code for my final solution. 这是我最终解决方案的代码。

I replaced: 我更换:

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

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

}

With: 附:

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

So now instead of pushing from controller to controller without popping any of them off of the stack, I pop all of the previous controllers up to the 'TableViewController' when 'Main' is clicked. 因此,现在单击“ Main”时,将所有以前的控制器弹出到“ TableViewController”,而不是从一个控制器到另一个控制器的推送而不将它们中的任何一个弹出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM