我的沙盒Mac应用程序(显然)正在泄漏文件资源(句柄?)。在向其添加文件(并将其中一些文件转换为其他格式)时,-[NSFileManager copyItemAtPath:toPath:error:]
上的文件会因此隐藏错误而失败:
NSUnderlyingError=0x600000440a50 "The operation couldn’t be completed. Too many open files"
我可以在Xcode之外(使用Debug版本)可靠地重现这个,但从不在里面。看起来某个地方的文件正在被打开而且从未关闭过。当我删除相同的文件夹时,它每次都出现在同一个文件中,如果我取出该文件,则会发生下一个文件。我记录了每个我能想到的地方我在NSFileManager
之外进行文件I / O的操作,看起来我的所有打开调用都与关闭平衡,我的调用启动和停止安全NSURLs
上的资源访问。
我尝试使用文件活动预设在Xcode之外的仪器中运行,并且能够重现其中的错误,但它看起来没有任何方法可以获得我需要的信息来自所使用的工具(文件活动,读/写,文件属性,目录I / O)。
答案 0 :(得分:1)
我最终能够使用仪器找出根本原因。我通过FD列对文件属性工具的事件列表进行了排序,并且能够看到有很多"打开"相同文件描述符的事件(以及相同文件和不同描述符的一些事件),没有任何"关闭"事件。我能够将违规代码追踪到我使用的库中。我在unit tests中使用此方法复制了它,并在运行某些代码之前和之后进行比较:
- (NSInteger)numberOfOpenFileHandles {
int pid = [[NSProcessInfo processInfo] processIdentifier];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/sbin/lsof";
task.arguments = @[@"-P", @"-n", @"-p", [NSString stringWithFormat:@"%d", pid]];
task.standardOutput = pipe;
[task launch];
NSData *data = [file readDataToEndOfFile];
[file closeFile];
NSString *lsofOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
// NSLog(@"LSOF:\n%@", lsofOutput);
return [lsofOutput componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]].count;
}