gpt4 book ai didi

cocoa - 如何使用确定的 NSProgressIndicator 来检查 NSTask 的进度? - cocoa

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

我所拥有的是 NSTask 运行一个很长的预制 shell 脚本,我希望 NSProgressIndicator 检查完成了多少。我尝试了很多事情,但似乎无法让它发挥作用。如果进度条不确定,我知道如何使用它,但我希望它随着任务的进行而加载。

这是我运行脚本的方式:

- (IBAction)pressButton:(id)sender {
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/sh"];
[task setArguments:[NSArray arrayWithObjects:[[NSBundle mainBundle] pathForResource:@"script" ofType:@"sh"], nil]];
[task launch];
}

我需要放置一个进度条,在任务发生时检查任务的进度并进行相应更新。

最佳答案

这是运行 unix 脚本的异步 NSTask 的示例。在 Unix 脚本中,有 echo 命令将当前状态发送回标准错误,如下所示:

回显“工作”>&2

这由通知中心处理并发送到显示器。

要更新确定的进度条,只需发送状态更新(例如“25.0”“26.0”)并转换为 float 并发送到进度栏。

注意:经过大量实验并使用本网站和其他引用文献中的许多技巧,我得到了这个工作。所以我希望它对你有帮助。

以下是声明:

NSTask *unixTask;
NSPipe *unixStandardOutputPipe;
NSPipe *unixStandardErrorPipe;
NSPipe *unixStandardInputPipe;
NSFileHandle *fhOutput;
NSFileHandle *fhError;
NSData *standardOutputData;
NSData *standardErrorData;

以下是主要程序模块:

    - (IBAction)buttonLaunchProgram:(id)sender {

[_unixTaskStdOutput setString:@"" ];
[_unixProgressUpdate setStringValue:@""];
[_unixProgressBar startAnimation:sender];

[self runCommand];
}
- (void)runCommand {

//setup system pipes and filehandles to process output data
unixStandardOutputPipe = [[NSPipe alloc] init];
unixStandardErrorPipe = [[NSPipe alloc] init];

fhOutput = [unixStandardOutputPipe fileHandleForReading];
fhError = [unixStandardErrorPipe fileHandleForReading];

//setup notification alerts
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

[nc addObserver:self selector:@selector(notifiedForStdOutput:) name:NSFileHandleReadCompletionNotification object:fhOutput];
[nc addObserver:self selector:@selector(notifiedForStdError:) name:NSFileHandleReadCompletionNotification object:fhError];
[nc addObserver:self selector:@selector(notifiedForComplete:) name:NSTaskDidTerminateNotification object:unixTask];

NSMutableArray *commandLine = [NSMutableArray new];
[commandLine addObject:@"-c"];
[commandLine addObject:@"/usr/bin/kpu -ca"]; //put your script here

unixTask = [[NSTask alloc] init];
[unixTask setLaunchPath:@"/bin/bash"];
[unixTask setArguments:commandLine];
[unixTask setStandardOutput:unixStandardOutputPipe];
[unixTask setStandardError:unixStandardErrorPipe];
[unixTask setStandardInput:[NSPipe pipe]];
[unixTask launch];

//note we are calling the file handle not the pipe
[fhOutput readInBackgroundAndNotify];
[fhError readInBackgroundAndNotify];
}
-(void) notifiedForStdOutput: (NSNotification *)notified
{

NSData * data = [[notified userInfo] valueForKey:NSFileHandleNotificationDataItem];
NSLog(@"standard data ready %ld bytes",data.length);

if ([data length]){

NSString * outputString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSTextStorage *ts = [_unixTaskStdOutput textStorage];
[ts replaceCharactersInRange:NSMakeRange([ts length], 0)
withString:outputString];
}

if (unixTask != nil) {

[fhOutput readInBackgroundAndNotify];
}

}
-(void) notifiedForStdError: (NSNotification *)notified
{

NSData * data = [[notified userInfo] valueForKey:NSFileHandleNotificationDataItem];
NSLog(@"standard error ready %ld bytes",data.length);

if ([data length]) {

NSString * outputString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[_unixProgressUpdate setStringValue:outputString];
}

if (unixTask != nil) {

[fhError readInBackgroundAndNotify];
}

}
-(void) notifiedForComplete:(NSNotification *)anotification {

NSLog(@"task completed or was stopped with exit code %d",[unixTask terminationStatus]);
unixTask = nil;

[_unixProgressBar stopAnimation:self];
[_unixProgressBar viewDidHide];

if ([unixTask terminationStatus] == 0) {
[_unixProgressUpdate setStringValue:@"Success"];
}
else {
[_unixProgressUpdate setStringValue:@"Terminated with non-zero exit code"];
}
}
@end

关于cocoa - 如何使用确定的 NSProgressIndicator 来检查 NSTask 的进度? - cocoa ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8889006/

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