2017-09-23 6 views
2

次のコードでは、4.75GBの不条理なメモリを使用するのはなぜですか?なぜFileManager.enumeratorは不当な量のメモリを使用しますか?

ファイルシステム内のすべてのファイルをループする方法はありますか?注

let filemanager:FileManager = FileManager() 
let root = "/" 
let files = filemanager.enumerator(atPath: root) 
while let element = files?.nextObject() { 
    // do nothing 
} 

(私はドライブ上の最大のファイルを検索しようとしている):私のファイルシステム(何も特別な)上の400Kのファイルがあります。コードはシーケンシャルなので、理論的にはファイルの数にも依存すべきではありません。

答えて

3

私はメモリグラフでそれを一時停止し、fileSystemRepresentation(withPath:)から割り当てられた不合理な数のNSConcreteDataインスタンスを表示します。

このドキュメントページには、現在の自動解放プールにのみ適したポインタが記載されています。これは解決策を示唆しています。nextObject()コールを独自の自動解放プールに取得するだけです。

このプログラムは、例えば、11.0メガバイトで着実にとどまる:全体まで保持スウィフトのwhile let構文はwhileループのコンテキストの自動解放プールに結合ますので、それぞれの要素が残っているよう

var done = false 
while !done { 
    autoreleasepool { 
     let element = files?.nextObject() 
     done = (element == nil) 

     // do nothing 
    } 
} 

に見えますループは完了する。

列挙子のオブジェクトを独自の自動解放プールに強制することで、後続の反復で保持されないことを確認できます。

EDIT:autoreleasepoolはちょうどfuncがあるので、私はこのはるかに簡潔に記述することができ:

while let element = autoreleasepool(invoking: { files?.nextObject() }) { 
    // do nothing 
} 
+0

はあなたが100%正しいです。私も「オートリリース」で遊んでいましたが、サイクルの中に入れていたので、それが役に立たなかったのです。あなたのソリューションは単に働いています。ありがとう!! – adamsfamily

関連する問題