gpt4 book ai didi

cocoa - 解决传递大量数据时 NSFileHandle NSTask 阻塞的问题

转载 作者:行者123 更新时间:2023-12-03 16:16:02 25 4
gpt4 key购买 nike

我有一些代码可以处理从我的应用程序导出数据。它接受一个充满 XML 的 NSString 并通过 PHP 脚本运行它来生成 HTMl、RTF 等。除非用户有一个很大的列表,否则它工作得很好。这显然是由于它超出了 NSPipe 8k 左右的缓冲区。

我在 readPipe 和 readHandle 中解决了这个问题(我认为),但我不确定如何在 writeHandle/writePipe 中处理它。应用程序将在 [writeHandle writeData:[in... 处进行沙滩球运动,除非我在 gdb 中中断它,等待几秒钟然后继续。

关于如何在我的代码中解决这个问题有什么帮助吗?

- (NSString *)outputFromExporter:(COExporter *)exporter input:(NSString *)input {
NSString *exportedString = nil;
NSString *path = [exporter path];
NSTask *task = [[NSTask alloc] init];

NSPipe *writePipe = [NSPipe pipe];
NSFileHandle *writeHandle = [writePipe fileHandleForWriting];
NSPipe *readPipe = [NSPipe pipe];
NSFileHandle *readHandle = [readPipe fileHandleForReading];

NSMutableData *outputData = [[NSMutableData alloc] init];
NSData *readData = nil;

// Set the launch path and I/O for the task
[task setLaunchPath:path];
[task setStandardInput:writePipe];
[task setStandardOutput:readPipe];

// Launch the exporter, it will convert the raw OPML into HTML, Plaintext, etc
[task launch];

// Write the raw OPML representation to the exporter's input stream
[writeHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];
[writeHandle closeFile];

while ((readData = [readHandle availableData]) && [readData length]) {
[outputData appendData:readData];
}

exportedString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
return exportedString;
}

最佳答案

自 10.7 起有一个新的 API,因此您可以避免使用 NSNotifications。

task.standardOutput = [NSPipe pipe];
[[task.standardOutput fileHandleForReading] setReadabilityHandler:^(NSFileHandle *file) {
NSData *data = [file availableData]; // this will read to EOF, so call only once
NSLog(@"Task output! %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

// if you're collecting the whole output of a task, you may store it on a property
[self.taskOutput appendData:data];
}];

您可能想对 task.standardError 重复上面的操作。

重要:

当你的任务终止时,你必须将 readabilityHandler block 设置为 nil;否则,您将遇到 CPU 使用率过高的情况,因为读取永远不会停止。

[task setTerminationHandler:^(NSTask *task) {

// do your stuff on completion

[task.standardOutput fileHandleForReading].readabilityHandler = nil;
[task.standardError fileHandleForReading].readabilityHandler = nil;
}];

这都是异步的(您应该异步执行),因此您的方法应该有一个 ^completion block 。

关于cocoa - 解决传递大量数据时 NSFileHandle NSTask 阻塞的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1395273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com