Swift UIKit内存管理效率低下

时间:2014-10-27 15:15:21

标签: memory memory-management swift

注意:如果有类似的问题我会道歉,但它们更具体,比如" UIMapView Kit内存泄漏问题",我更关心并且真的想知道Swift和ARC的常规以及内存管理问题。

我现在已经在Xcode中完成了几个应用程序,但它们都是在Objective-C中完成的。

UIKit对象(包括UIViews和UIViewControllers)的内存管理以及任何其他对象在Objective-C中都很容易处理,而且我很容易意味着在学习中的某个时刻与它对抗后再习惯它曲线。

现在我正在与Swift一起努力跟上"前沿"技术。但是我注意到在Objective-C,Memory Management中我能够确定和控制的一个小问题。

Swift表示,对于我们来说,更多地关注代码开发而不是内存管理(如其前身或即将成为的前身)是多么容易。 但是我还没有发现这个好处。我的新应用程序的内存管理一直很糟糕。只需创建一个带有少量视图的简单UIViewController就可以叠加我不再需要的内存,一次只需要很少的Mb。

请记住,我一直在使用解构函数(在Swift中使用Deinit),为不再需要使用的值分配nil,手动从Super Views中删除SubViews,认为这是问题,甚至使用AutoReleasePool代码段。

autoreleasepool{
//Code looping through Swift Native Objects that potentially might lead to leaking 
//But AutoReleasePool helps with this, supposedly.
}

现在的问题:这里的任何人都知道到底是什么问题?是我用我的代码做了一些可怕的事情吗?或者Xcode和swift内存管理中是否真的存在错误?有没有其他人有这个问题,你解决了吗?

这是一个解释这种情况的链接。 Problems of ARC in Swift? ARC in Swift Apple Docs


更新:

你是对的,我应该更多地讲述我的情况:所以就这样了。

应用程序启动后,我的内存从〜5mb开始。

一旦我开始浏览应用程序。我注意到记忆开始逐渐堆积起来。 但是当我使用大约25 Mbs的UIMapView时,最大的内存峰值开始堆积。

当只使用常规UITableViewController时,每次推送(到NavController)相同的UITableViewController时,它只会堆积~2mbs。当我选中TableViewCell它打开另一个带有UIMapView的ViewController时,这就是内存开始积累的好地方。

记住我只是在应用程序中来回导航。总共有4个UIViewControllers,包括My Menu。

但事情就是这样......你看到的所有这些内存SnapShots都是在我停止导航并返回主菜单后,我的导航控制器的Root ViewController。

Starting App Opening UiTableViewController Opening ViewController with UIMapView Stacking that Memory Up

1 个答案:

答案 0 :(得分:2)

Swift以与ObjC完全相同的方式使用ARC。如果您发现泄漏,您可能会在某处创建一个保留循环,并且您可以避免使用与ObjC几乎完全相同的方式(使用无主的附加选项,但这些非常相似) to unsafe_unretained,所以即使这不是重大改变)。如果你熟悉Cocoa中的内存管理,那么你就能理解Swift中的内存管理。但是,根据您在此处提供的信息(主要是对Cocoa的评论),我们无法提供帮助。

autoreleasepool{
//Code looping through Swift Native Objects that potentially might lead to leaking 
//But AutoReleasePool helps with this, supposedly.
}

所有这一切,这个评论暗示你的错误。自动释放池需要在内部循环,在那里你快速创建和销毁对象,而不是围绕它。自动释放的对象直到池块结束或事件循环结束才会释放。后者通常是足够的,但如果您生成并释放大量物体,那么有时您必须尽快排空池。自动释放池在Advanced Memory Management Programming Guide中说明。也就是说,UIKit对象通常不需要它们。

作为旁注,Swift中的ARC问题是什么?"你给的链接似乎不知道Cocoa垃圾收集的历史。 GC在Mac上尝试使用GC,并被Cocoa开发者拒绝。 Apple弃用了GC并随后将其删除了(当他们宣布它被弃用时,我在WWDC;我们鼓掌)。它甚至不适用于iOS。关于这个问题的一个很好的讨论是Why mobile web apps are slow。我并不是说GC是一件坏事。我说苹果很清楚它,并积极选择不加入它。他们并没有错过任何机会。


编辑:您的更新信息看起来像一个非常标准的保留循环。我从heap shot analysis开始,找出所涉及的对象类型。确保你following the rules。从那里开始,主要是使用仪器(特别是Allocations和Leaks仪器)。一个关键是视图控制器通常不应该保留其他视图控制器。他们应该通过模型相互交谈。您必须小心使用块中的self。正常规则。他们在ObjC和Swift中都是一样的。但堆射绝对是开始的地方。找出什么是泄漏;然后找出原因。