使用NSThread创建线程,执行NSTask,但是异步读取pipe的时候出错

使用NSThread创建线程,执行NSTask,但是异步读取pipe的时候出错   

想要创建一个线程,然后执行shell命令,并且是异步的读取shell命令返回的信息 
 
目前的问题是: 
1、不用线程,直接使用异步读取,结果是正确的 
2、不用异步读取,可以使用线程,而且从shell返回的信息是正确的 
3、但是不能开线程,同时还用下面的方法来异步读取… 
 
追加提问: 
1、如果我想要让新开线程中的shell指令,我还能够根据shell返回的信息,进行判断,请问应该怎么办? 
(比方说,同级执行的次数,然后显示在一个NSTextField里面?) 
 
 
 
复制代码
  1. - (IBAction)openShell: (id)sender
  2. {
  3.     [NSThread detachNewThreadSelector:@selector(doshell:) toTarget:self withObject:nil];
  4. }
 
 
 
然后,在doshell函数里面,运行NSTask 
复制代码
  1. - (void) doshell:(id)anObject
  2. {
  3.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  4. // Is the task running?
  5.     if (task) {
  6.         [task interrupt];
  7.     } else {
  8.         task = [[NSTask alloc] init];
  9.         [task setLaunchPath:@"/sbin/ping"];
  10.         NSArray *args = [NSArray arrayWithObjects:@"-c10",
  11.                                         [hostField stringValue], nil];
  12.         [task setArguments:args];
  13.         // Release the old pipe
  14.         [pipe release];
  15.         // Create a new pipe
  16.         pipe = [[NSPipe alloc] init];
  17.         [task setStandardOutput:pipe];
  18.         NSFileHandle *fh = [pipe fileHandleForReading];
  19.         NSNotificationCenter *nc;
  20.         nc = [NSNotificationCenter defaultCenter];
  21.         [nc removeObserver:self];
  22.         [nc addObserver:self
  23.                selector:@selector(dataReady:)
  24.                    name:NSFileHandleReadCompletionNotification
  25.                  object:fh];
  26.         [nc addObserver:self
  27.                selector:@selector(taskTerminated:)
  28.                    name:NSTaskDidTerminateNotification
  29.                  object:task];
  30.         [task launch];
  31.         [outputView setString:@""];
  32.         [fh readInBackgroundAndNotify];
  33.     }
  34.     [pool release];
  35.     [NSThread exit];
  36. }
 
 
 
之后就是完成相应的消息 
复制代码
  1. - (void)appendData:(NSData *)d
  2. {
  3.     NSString *s = [[NSString alloc] initWithData:d
  4.                                        encoding:NSUTF8StringEncoding];
  5.     NSTextStorage *ts = [outputView textStorage];
  6.     [ts replaceCharactersInRange:NSMakeRange([ts length], 0)
  7.                       withString:s];
  8.     [s release];
  9. }
  10. - (void)dataReady:(NSNotification *)n
  11. {
  12.     NSData *d;
  13.     d = [[n userInfo] valueForKey:NSFileHandleNotificationDataItem];
  14.     NSLog(@"dataReady:%d bytes", [d length]);
  15.     if ([d length]) {
  16.         [self appendData:d];
  17.     }
  18.     // If the task is running, start reading again
  19.     if (task)
  20.         [[pipe fileHandleForReading] readInBackgroundAndNotify];
  21. }
  22. - (void)taskTerminated:(NSNotification *)note
  23. {
  24.     NSLog(@"taskTerminated:");
  25.     [task release];
  26.     task = nil;
  27.     [startButton setState:0];
  28. }
 
 
 
请各位帮忙看看~谢谢了 
任何建议都可以,如果懒得给我代码,说我那个方面比较欠缺,我可以自己去看 
谢谢!

下面方法有点投机,还是想要继续求得一个使用通告的方法^_^
解决了,但是好像感觉有点投机… 
 
首先在运行的NSTask里面再开一个新线程 
复制代码
  1.         [NSThread detachNewThreadSelector:@selector(copyData:) toTarget:self withObject:fh];
 
 
 
然后,实现方法就行了 
复制代码
  1. - (void)copyData:(NSFileHandle*)handle 
  2. {
  3.     NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
  4.     NSData *data;
  5.     
  6.     while([data=[handle availableData] length]) 
  7.     {
  8.         NSString *string=[[NSString alloc] initWithData:data
  9.                                                encoding:NSASCIIStringEncoding];
  10.         NSRange theEnd=NSMakeRange([[outputView string] length],0);
  11.         
  12.         [outputView replaceCharactersInRange:theEnd
  13.                                 withString:string]; // append new string to the end
  14.         theEnd.location+=[string length]; // the end has moved
  15.         [outputView scrollRangeToVisible:theEnd];
  16.         
  17.         [string release];
  18.     }
  19.     
  20.     [pool release];
  21. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值