iOS开发Swift

Swift 循环中内存狂飙的问题

近期开发IOS APP过程中,发现内存飙升的情况,IOS 明明有 ARC ,明明释放了内存,却还是让程序的内存占用随着循环而一路飙升。。

上面这种情况,在for循环中,读取文件,并把文件内存赋值给for循环中定义的临时变量a。但是测试中发现,在每一次循环过程中,a的消耗内存并没有释放,是累加的。只有当整个for循环结束以后,这个累加的内存才被释放掉。

这里其实并不是出现了内存泄露,这其实是 ARC 的一个机制:在每一个主 Runloop 结束的时候进行清理。也就是说,它有一套必要的缓存机制——毕竟,实时释放的话谁能保证你的局部变量要不要留下来给后续的代码使用呢?

但显然,这个必要的机制在这个时候成了我们的噩梦。

这里我们假定这个 loadBigData() 是一个加载文件略大又费事的动作,那么按照想法,这个文件在每次循环都会被释放——毕竟是个循环内的局部变量,但实际上由于 ARC 的缓存机制,内存就会一直变大。

这个时候,我们可以说 ARC 并不是很智能,所以一旦遇到这种情况,那么就需要人工对 ARC 进行干预,来达到更好的内存管理效果。

在 Swift 中,我们使用这个全局函数:

可以看到,它是一个泛型声明,返回的类型根据你传入的闭包而定。我们要做的就是将需要计算的内容放入这个函数中进行计算,这样就相当于是临时把为这个内容开放的内存标记为不要缓存,那么 ARC 不会等到 Runloop 结束才回收,而是在用完后立即回收内存资源,比如说改成这样:

这样,计算完成的内容就会立即被清理掉,程序的行为才真正符合我们的本意。

最后还是要补一句,这里我们的 loadBigData() 指代的是一个加载大文件然后获取想要的数据再返回的过程,并非初始化一个类,如果是通过类初始化比如 Dafa(URL:url) 这样的初始化方法,ARC 是能够自动管理的。这里我们讨论的是一种非常特殊的情况——毕竟大家编程这么久,也并不一定会碰到几次。