当视图控制器被解除时,它是否应该清空内存?

时间:2015-05-14 20:02:42

标签: ios objective-c memory-management uiviewcontroller automatic-ref-counting

我想学习Objective-C中的内存管理,我发现这并不容易,因为我在Objective-C和ARC方面相当新,而且我主要用来编写我没有的语言用内存管理来处理那么多(或根本没有)。

我正在处理的应用程序是在按下按钮后从代码中呈现一个viewController(附带xib文件)。在这个视图控制器中,我实例化了几个视图;我记录了一系列图像(照片来自相机,保存到磁盘),我转换为电影,我有一个gps跟踪器(mapKit),它在屏幕上显示一个小地图。完成所有操作后,我可以按下“完成”按钮,调用[self dismissViewControllerAnimated:YES completion:nil];

viewController动画回到我的rootViewController,因为我在viewController中的NSLog方法中放了一个dealloc消息,我被确认这个viewController正被解除分配。

问题是我看到使用应用程序后的内存上升(使用情况包括在MapKit地图上拍摄和录制gps位置以及生成电影文件)到大约80 MB,这下降到大约70MB当我按下'done'时,viewController会解散,app会返回我的rootViewController。我可以再次呈现相同的viewController,使用它并解除它,应用程序仍将占用大约70MB的内存,不会掉线。这对我来说看起来并不像是内存泄漏,因为在这种情况下,我希望每次实例化和解除viewController都能稳定上升内存。即使我的rootViewController中有不同的按钮,它们都实例化了我的viewController类的一个新的独特实例,但情况并非如此。

我想知道:有什么我应该寻找的,还是这种预期的行为?也许该应用程序是缓存类以供将来使用?在内存管理正确的情况下,我应该期待一个应用程序在解除所呈现的唯一viewController之后恢复到“处女”内存状态(在这种情况下,这将是大约4 MB)?

2 个答案:

答案 0 :(得分:8)

如果您在Xcode中看到此内存上升而未使用乐器,那么the answer I have come up with is in this answer.

你可以阅读整个答案,这是非常深入的。但长话短说,在Xcode中,您可以看到操作系统“给予”您的应用程序使用的内存量。这会增加您的应用尝试分配内容的任何时间。它并没有那么快地减少,因为操作系统会进行性能猜测,认为您的应用程序将来可能需要更多内存。操作系统将“给定”内存留给您的应用程序比将其取下并稍后将其还原更快。

答案 1 :(得分:2)

当视图控制器没有被其他对象使用时(或者没有与尚未从内存中删除的其他对象的强连接),应该从内存中清除它。

实施例

class ViewController: UIViewController {
    var secondViewController: SecondViewController?
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let identifier = segue.identifier {
            if identifier == "second" {
                if secondViewController == nil {
                    secondViewController = segue.destinationViewController as? SecondViewController
                } else {
                    println("There's still an instance of second view controller")
                }
            }
        }
    }
}

假设您第一次使用storyboard segue呈现了secondViewController,并将其作为属性存储在ViewController的实例中。然后,你关闭了第二个ViewController,并再次从ViewController中显示第二个ViewController,它将打印“还有一个第二个视图控制器的实例”,因为你之前提到的那个仍被ViewController使用。

然而,当secondViewController具有弱连接时,(weak var secondViewController: SecondViewController),它将永远不会打印,因为从第二个ViewController被解除的那一刻起,它将被从内存中删除,而secondViewController将是零。

编辑

注意:使用Objective-C时结果应该相同。