想要创建一个线程,然后执行shell命令,并且是异步的读取shell命令返回的信息
目前的问题是:
1、不用线程,直接使用异步读取,结果是正确的
2、不用异步读取,可以使用线程,而且从shell返回的信息是正确的
3、但是不能开线程,同时还用下面的方法来异步读取…
追加提问:
1、如果我想要让新开线程中的shell指令,我还能够根据shell返回的信息,进行判断,请问应该怎么办?
(比方说,同级执行的次数,然后显示在一个NSTextField里面?)
复制代码
- - (IBAction)openShell: (id)sender
- {
- [NSThread detachNewThreadSelector:@selector(doshell:) toTarget:self withObject:nil];
- }
|
然后,在doshell函数里面,运行NSTask
复制代码
- - (void) doshell:(id)anObject
- {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- // Is the task running?
- if (task) {
- [task interrupt];
- } else {
- task = [[NSTask alloc] init];
- [task setLaunchPath:@"/sbin/ping"];
- NSArray *args = [NSArray arrayWithObjects:@"-c10",
- [hostField stringValue], nil];
- [task setArguments:args];
-
- // Release the old pipe
- [pipe release];
- // Create a new pipe
- pipe = [[NSPipe alloc] init];
- [task setStandardOutput:pipe];
-
- NSFileHandle *fh = [pipe fileHandleForReading];
-
- NSNotificationCenter *nc;
- nc = [NSNotificationCenter defaultCenter];
- [nc removeObserver:self];
- [nc addObserver:self
- selector:@selector(dataReady:)
- name:NSFileHandleReadCompletionNotification
- object:fh];
- [nc addObserver:self
- selector:@selector(taskTerminated:)
- name:NSTaskDidTerminateNotification
- object:task];
- [task launch];
- [outputView setString:@""];
-
- [fh readInBackgroundAndNotify];
- }
- [pool release];
- [NSThread exit];
- }
|
之后就是完成相应的消息
复制代码
- - (void)appendData:(NSData *)d
- {
- NSString *s = [[NSString alloc] initWithData:d
- encoding:NSUTF8StringEncoding];
- NSTextStorage *ts = [outputView textStorage];
- [ts replaceCharactersInRange:NSMakeRange([ts length], 0)
- withString:s];
- [s release];
- }
-
- - (void)dataReady:(NSNotification *)n
- {
- NSData *d;
- d = [[n userInfo] valueForKey:NSFileHandleNotificationDataItem];
-
- NSLog(@"dataReady:%d bytes", [d length]);
-
- if ([d length]) {
- [self appendData:d];
- }
-
- // If the task is running, start reading again
- if (task)
- [[pipe fileHandleForReading] readInBackgroundAndNotify];
- }
-
- - (void)taskTerminated:(NSNotification *)note
- {
- NSLog(@"taskTerminated:");
-
- [task release];
- task = nil;
-
- [startButton setState:0];
-
- }
|
请各位帮忙看看~谢谢了
任何建议都可以,如果懒得给我代码,说我那个方面比较欠缺,我可以自己去看
谢谢!
下面方法有点投机,还是想要继续求得一个使用通告的方法^_^
解决了,但是好像感觉有点投机…
首先在运行的NSTask里面再开一个新线程
复制代码
- [NSThread detachNewThreadSelector:@selector(copyData:) toTarget:self withObject:fh];
|
然后,实现方法就行了
复制代码
- - (void)copyData:(NSFileHandle*)handle
- {
- NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
- NSData *data;
-
- while([data=[handle availableData] length])
- {
- NSString *string=[[NSString alloc] initWithData:data
- encoding:NSASCIIStringEncoding];
- NSRange theEnd=NSMakeRange([[outputView string] length],0);
-
- [outputView replaceCharactersInRange:theEnd
- withString:string]; // append new string to the end
- theEnd.location+=[string length]; // the end has moved
- [outputView scrollRangeToVisible:theEnd];
-
- [string release];
- }
-
- [pool release];
- }
|