无限的内存增长 - iOS

时间:2014-03-25 14:24:45

标签: ios objective-c swift memory-management properties

以下解决

我正在阅读raywenderlich博客上的这篇文章: http://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode 了解乐器并弄清楚我是否在某些旧项目中做错了。

我已经看到,在我的代码的一个特定点上,当我显示最终关闭的模态视图时,分配的内存仍然存在。如下图所示。

enter image description here

执行生成了4个标记。 在2n和3t标记之间,显示视图,如您所见,分配了新内存。 但是在3t和4之间,我调用了dismissViewController,视图不再存在。但记忆仍然是分配的。

所有属性都是强大的(可能不是最好的方法):

enter image description here enter image description here

我有一个NSTimer,它在viewDidLoad方法中初始化,并在viewWillDisappear设置为nil:

[self.secondTimer invalidate];
self.secondTimer = nil;

那么,你对发生的事情有什么看法吗?据我所知,即使属性被声明为强大,当UIViewController被释放时,所有这些属性都将被释放。

修改

感谢所有人,我提供的信息还不够。

如您所见,QRViewController继承自BaseViewController。

这个控制器有一个委托定义为强存储,很糟糕。

所以就是这样。

3 个答案:

答案 0 :(得分:2)

在视图控制器层次结构中,self.view将所有子视图保存为strong,因此self.view下的所有内容(可能是您的所有IBOutlet属性)都可以切换为{{1 }}。但这可能无法解决问题。

可能对您有所帮助的是,您拥有的任何weak都将该块中使用的每个对象都保存为强,以确保该块可以暂时运行它的代码。如果没有任何东西阻挡那个阻挡(比如block)而不是担心。但是如果你有一个对象持有的任何块(喜欢和对象的“完成块”或任何其他创造性的块使用),那个块中的所有内容都将是animationWithDuration:,并且你有可能创建一个保留周期那样。例如:呈现视图控制器使用完成块调用呈现的视图控制器,并在该块中使用strong。现在呈现VC持有一个块来执行解除,并且该块保持呈现VC。当被解雇时,你最终会得到一个VC,它持有一个包含VC的块,该VC保存所呈现的VC ....

一个简单的解决方案是为块提供self版本的weak,并且仅在块执行时,在运行块时使其为self(以避免dealloc在运行块时):

strong

答案 1 :(得分:0)

很难确切地指出这个问题,但通常当这样的事情发生在我身上时,它会成为一个(或几个)“根”罪魁祸首 - 你会找到一个,清除它,然后很多其他人也清理了。因此,您可以尝试的一种策略是筛选Instruments数据,寻找任何类型的“层次结构”(考虑您的应用程序的结构以及对象如何相互关联)并寻找更靠近基础的对象,然后交叉针对您的代码的引用,以查看它们是否可能有保留周期或其他类似问题。

我要做的一个即时更改是将IBOutlet声明从strong更改为weak。对于层次结构内的对象,大多数情况下IBOutlet属性应为weak。因此,如果您在xib的主UILabel中有一些view,那么该标签应该被弱保留,以避免保留周期。但是,如果说UILabel单独作为xib中的根项目,则需要strong引用。我猜测你的IBOutlet中的大多数(如果不是全部)都在层次结构中,所以请将它们weak再试一次。它可能无法解决所有泄漏,但看看它是否有任何不同。

答案 2 :(得分:0)

这称为弃置内存,请检查此link

提示 如果您在视图控制器之间导航,并且在闭包内执行导航,则应使用weakunownedself,例如:

    //Swift 2.1
    //Performing naivgation on the main thread for responsiveness:
    dispatch_async(dispatch_get_main_queue(), {[weak self] () -> Void in

        if let weakSelf = self{

            weakSelf.performSegueWithIdentifier("myOtherView", sender: weakSelf)

        }
    })

此外,解雇视图控制器时也是如此:

dispatch_async(dispatch_get_main_queue(), {[weak self] () -> Void in

            if let weakSelf = self{

            weakSelf.dismissViewControllerAnimated(true, completion: nil)

            }
})

上面发布的链接显示了如何使用Xcode Instruments捕获abanodend内存的实际示例。