Objective C 将标准输出打印到 UIAlertView

JML*_*dev 1 stdout objective-c nsfilehandle ios

我有一个使用 打印到 stdout 的 C 函数fprintf,并且我试图在UIAlertView. 我的代码如下:

NSFileHandle *stdoutFileHandle = [NSFileHandle fileHandleWithStandardOutput];
NSData *stdoutData = [stdoutFileHandle availableData];
NSString *stdoutString = [[NSString alloc] initWithData:stdoutData encoding:NSASCIIStringEncoding];

UIAlertView *stdoutAlert = [[UIAlertView alloc] initWithTitle:@"STDOUT OUTPUT" message:stdoutString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[stdoutAlert show];
Run Code Online (Sandbox Code Playgroud)

当我运行我的代码时,出现以下错误。

由于未捕获的异常“NSFileHandleOperationException”而终止应用程序,原因:“[NSConcreteFileHandle availableData]:错误的文件描述符”

[stdoutFileHandle availableData]当我替换为时,我收到了等效的错误[stdoutFileHandle readDataToEndOfFile]

Jef*_*mas 5

问题是您正在从输出流读取。为了完成这项工作,您需要欺骗 stdout 将其内容写入输入流而不是控制台。

我知道旧的 C 方法可以做到这一点,但你不会喜欢它。这里用到了pipe ()和dup2 ()。

int pipefd[2];

pipe(pipefd);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
Run Code Online (Sandbox Code Playgroud)

此时,写入 stdout 的任何内容都可以由 读取pipefd[0]。此时您可以使用-initWithFileDescriptor:来读取pipefd[0].

NSFileHandle *stdoutReader = [[NSFileHandle alloc] initWithFileDescriptor:pipefd[0]];
Run Code Online (Sandbox Code Playgroud)

请注意,您将需要进行大量错误检查。希望有帮助。


Thi*_*obo 5

我按照这个问题中选定的答案帖子进行操作: What is the best way to redirect stdout to NSTextView in Cocoa?

对我来说,跟随感觉有点熟悉。我为管道和读取处理程序创建了一个 NSPipe 和 NSFileHandler 对象,并使用了通知。由于我的需要,我将 open 方法放在 viewDidAppear 和 viewDidDisappear 方法中,但您可以将其放在适当的位置

// Piping stdout info from here WILL NOT PIPE NSLOG:
// /sf/ask/168434311/
- (void) openConsolePipe {
    _pipe = [NSPipe pipe];
    _pipeReadHandle = [_pipe fileHandleForReading] ;
    dup2([[_pipe fileHandleForWriting] fileDescriptor], fileno(stdout)) ;

    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNotification:) name: NSFileHandleReadCompletionNotification object: _pipeReadHandle] ;
    [_pipeReadHandle readInBackgroundAndNotify] ;
}

- (void) closeConsolePipe {
    if (_pipe != nil) {
        [[_pipe fileHandleForWriting] closeFile];

        // documentation suggests don't need to close reading file handle b/c auto but this suggests otherwise:
        // /sf/ask/962306271/
//        [[_pipe fileHandleForReading] closeFile];
    }
}

- (void) handleNotification:(NSNotification *)notification {
    [_pipeReadHandle readInBackgroundAndNotify] ;
    NSString *str = [[NSString alloc] initWithData: [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] encoding: NSUTF8StringEncoding];

    // do what you want with the str here.
    [_consoleView setText:[_consoleView.text stringByAppendingString:str]];
    [_consoleView scrollRangeToVisible:NSMakeRange([_consoleView.text length], 0)];
}
Run Code Online (Sandbox Code Playgroud)

我希望这最终能帮助其他人搜索这个......