Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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
Cocoa NSTask标准输出占用大量内存_Cocoa_Nstask - Fatal编程技术网

Cocoa NSTask标准输出占用大量内存

Cocoa NSTask标准输出占用大量内存,cocoa,nstask,Cocoa,Nstask,我正在通过NSTask运行一个命令,该命令生成大量输出。我创建了一个连接到标准输出的管道,正在使用WaitForDataInBackground和Notify,并使用availableData使用数据。然而,随着应用程序分配的内存不断增长,所有输出似乎都被缓冲。如何清除/使用发送到stdout的数据?以下是我正在使用的代码: - (void)runCommand:(NSString *)commandToRun { self.task = [[NSTask alloc] init];

我正在通过NSTask运行一个命令,该命令生成大量输出。我创建了一个连接到标准输出的管道,正在使用WaitForDataInBackground和Notify,并使用availableData使用数据。然而,随着应用程序分配的内存不断增长,所有输出似乎都被缓冲。如何清除/使用发送到stdout的数据?以下是我正在使用的代码:

- (void)runCommand:(NSString *)commandToRun
{
    self.task = [[NSTask alloc] init];
    [self.task setLaunchPath: @"/bin/sh"];
    NSArray *arguments = [NSArray arrayWithObjects:
                          @"-c" ,
                          [NSString stringWithFormat:@"%@", commandToRun],
                          nil];
    [self.task setArguments: arguments];
    NSPipe *pipe = [NSPipe pipe];
    [self.task setStandardOutput:pipe];
    NSFileHandle *fh = [pipe fileHandleForReading];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedData:) name:NSFileHandleDataAvailableNotification object:fh];
    [fh waitForDataInBackgroundAndNotify];
    [self.task launch];
}

- (void)receivedData:(NSNotification *)notification
{
    NSFileHandle *fh = [notification object];
    NSData *data = [fh availableData];
    // do stuff...
    [fh waitForDataInBackgroundAndNotify];
}

你的
工作
实际上对
数据
做了什么?我怀疑它正在保留对它的强引用或将其复制到其他内存中的数据结构中。当我注释掉所有
内容时,果然内存分配不再增长,所以您是对的,这不是一个NSTask/NSPipe/等问题。但我看不出我在哪里保留了对
数据的任何引用。将
receivedData
的内容封装在
@autoreleasepool
中解决了该问题。我想知道ARC是否决定保留所有分配,直到
task
发布(我刚刚编辑了问题中的代码,以反映
task
确实是保留属性)?或者说,
@autoreleasepool
刚刚屏蔽了一个仍然存在的问题吗?@stdout:自动删除能够“屏蔽”内存问题的唯一方法是,如果您的问题是您同时分配了一堆内存;自动释放将帮助您摆脱它,但您的“高水位线”,如苹果所称,仍然会很高。它不会“掩盖”漏洞。你在用ARC吗?而且,正如Ken Thomases已经问过的,你在“做事情”中做什么?另一个可能有用的原因是,如果没有任何东西会定期将自动释放池中的水排到所示的方法之外。例如,如果这不是由应用程序的主线程调用的,而是由自定义线程或命令行工具调用的。显然,正在运行一个运行循环(因为正在接收数据),但不一定是以这样一种方式,即周围的自动释放池被耗尽。