Pho*_*ixS 9 cocoa real-time nstask nsnotifications nsnotificationcenter
我有一个Cocoa命令行程序,我尝试运行NSTask
程序(tshark
监视网络)并从中实时获取数据.所以我创建了一个NSFileHandle,调用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;
}
Run Code Online (Sandbox Code Playgroud)
编辑:当我取消注释已注释的代码段并删除所有通知内容时,在任务完成后从文件句柄中提取所有需要的数据.
我也想知道,如果问题不能实际上,我的程序是'命令行工具'所以我不确定它是否已经运行循环 - 正如Apple文档所说的那样(在NSFileHandle的waitForDataInBackgroundAndNotify消息中):
您必须从具有活动运行循环的线程调用此方法.
sup*_*rin 10
自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];
}];
Run Code Online (Sandbox Code Playgroud)
可能你想重复上面的相同task.standardError
.
重要:
当您的任务终止时,您必须将readabilityHandler块设置为nil; 否则,您将遇到高CPU使用率,因为读数永远不会停止.
[task setTerminationHandler:^(NSTask *task) {
// do your stuff on completion
[task.standardOutput fileHandleForReading].readabilityHandler = nil;
[task.standardError fileHandleForReading].readabilityHandler = nil;
}];
Run Code Online (Sandbox Code Playgroud)
这都是异步的(你应该做异步),所以你的方法应该有一个^完成块.
归档时间: |
|
查看次数: |
2926 次 |
最近记录: |