gpt4 book ai didi

cocoa - 使用通知从 NSTask 实时获取数据不起作用

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

我有一个 Cocoa 命令行程序,我尝试在其中运行 NSTask 程序(tshark 来监视网络)并从中实时获取数据。所以我做了一个 NS文件句柄,调用waitForDataInBackgroundAndNotify发送通知,然后将我的帮助类注册到通知中心来处理数据,但没有一个通知发送到我的帮助类。

有人知道可能出了什么问题吗?

提前致谢

这是我的代码:

#import <Foundation/Foundation.h>
#import <string>
#import <iostream>

@interface toff : NSObject {}
-(void) process:(NSNotification*)notification;
@end

@implementation toff
-(void) process:(NSNotification*)notification{
printf("Packet caught!\n");
}
@end

int main (int argc, const char * argv[]){
@autoreleasepool {
NSTask* tshark = [[NSTask alloc] init];
NSPipe* p = [NSPipe pipe];
NSFileHandle* read = [p fileHandleForReading];
toff* t1 = [[toff alloc] init];
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];

[read waitForDataInBackgroundAndNotify];
[nc addObserver:t1 selector:@selector(process:) name:nil object:nil];

printf("Type 'stop' to stop monitoring network traffic.\n");
[tshark setLaunchPath:@"/usr/local/bin/tshark"];
[tshark setStandardOutput:p];
[tshark launch];

while(1){
std::string buffer;
getline(std::cin, buffer);
if(buffer.empty()) continue;
else if(buffer.compare("stop") == 0){
[tshark interrupt];
break;
}
}

//NSData* dataRead = [read readDataToEndOfFile];
//NSLog(@"Data: %@", dataRead);
//NSString* stringRead = [[NSString alloc] initWithData:dataRead encoding:NSUTF8StringEncoding];
//NSLog(@"Output: %@", stringRead);

}
return 0;
}

编辑:当我取消注释代码的注释部分并删除所有通知内容时,任务完成后将从文件句柄中提取所有所需的数据。

我还想知道,如果问题实际上不可能是我的程序是“命令行工具”,所以我不确定它是否有运行循环 - 正如苹果文档所说需要的(在 NSFileHandle 的 waitForDataInBackgroundAndNotify 消息中) :

You must call this method from a thread that has an active run loop.

最佳答案

自 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 - 使用通知从 NSTask 实时获取数据不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8945770/

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