Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion Can';在Swift应用程序中找不到内存泄漏_Recursion_Memory Leaks_Swift - Fatal编程技术网

Recursion Can';在Swift应用程序中找不到内存泄漏

Recursion Can';在Swift应用程序中找不到内存泄漏,recursion,memory-leaks,swift,Recursion,Memory Leaks,Swift,我正在努力学习Swift,因此为此我编写了一个小测试应用程序。它只给出目录中项目的总大小,递归到子目录以累积其内容的总大小。应用程序可以工作,但内存使用量在运行时不断增长。我原以为随着递归的深入,内存使用会增加,而当递归调用返回时,内存使用会减少。相反,内存使用率只是不断攀升。仪器没有发现任何泄漏。我尝试了一些在各种谷歌搜索结果中找到的技巧,包括: 重新使用默认的NSFileManager 不是重复使用默认的NSFileManager,而是为每个递归调用创建一个新的NSFileManager 避

我正在努力学习Swift,因此为此我编写了一个小测试应用程序。它只给出目录中项目的总大小,递归到子目录以累积其内容的总大小。应用程序可以工作,但内存使用量在运行时不断增长。我原以为随着递归的深入,内存使用会增加,而当递归调用返回时,内存使用会减少。相反,内存使用率只是不断攀升。仪器没有发现任何泄漏。我尝试了一些在各种谷歌搜索结果中找到的技巧,包括:

重新使用默认的NSFileManager 不是重复使用默认的NSFileManager,而是为每个递归调用创建一个新的NSFileManager 避免字符串插值

似乎没什么不同。我原以为斯威夫特会在参考计数为零时清理对象

这是当前状态下的完整代码:

import Foundation

func sizeOfContents(path: String) -> UInt64
{
    let subManager = NSFileManager()
    var totalSize: UInt64 = 0;
    var isDir: ObjCBool = false
    if subManager.fileExistsAtPath(path, isDirectory: &isDir)
    {
        if !isDir.boolValue
        {
            var error: NSError? = nil
            let attributes: NSDictionary? = subManager.attributesOfItemAtPath(path, error: &error)
            let size: UInt64? = attributes?.fileSize()
            totalSize += size!
        }
        else
        {
            var error: NSError? = nil
            if let subContents = subManager.contentsOfDirectoryAtPath(path, error: &error)
            {
                for subItem in subContents
                {
                    var subName = subItem as String
                    subName = path + "/" + subName
                    totalSize += sizeOfContents(subName)
                }


            }
        }
    }

    return totalSize
}

let manager = NSFileManager.defaultManager()
var rootPath = "/Applications/"
if let contents = manager.contentsOfDirectoryAtPath(rootPath, error: nil)
{
    for item in contents
    {
        let itemName = item as String
        var isDir: ObjCBool = false
        print("item: " + (rootPath + itemName))
        if manager.fileExistsAtPath(rootPath + itemName, isDirectory: &isDir)
        {
            if !isDir.boolValue
            {
                var error: NSError? = nil
                let attributes: NSDictionary? = manager.attributesOfItemAtPath(rootPath + itemName, error: &error)
                let size: UInt64? = attributes?.fileSize()
                println("\t\(size!)")
            }
            else
            {
                if(itemName != "Volumes")
                {
                    let size = sizeOfContents(rootPath + itemName)
                    println("\t\(size)")
                }
            }
        }
    }
}

您需要在循环中添加一个autoreleasepool,可能是围绕递归调用。由于它是一个紧循环,空闲循环没有得到释放临时内存分配的更改

例如:

...
autoreleasepool {
    totalSize += sizeOfContents(subName)
}
...

就这样。现在我得去读一下autoreleasepool。当我从“/”开始运行该应用程序时,它的容量从未超过6.4MB,而之前它的容量超过60GB,而且运行速度更快。它从未在Swift编程语言书中提到过,但我确实在WWDC会议中找到了一些关于它的内容(用仪器改进你的应用程序)。谢谢!