8

Stdout を NSTextView にリダイレクトする方法を教えてもらえますか?

NSLogによる情報出力がstdに属しているかどうか?

ありがとう

4

3 に答える 3

10

以下のコードはdup2、stdout をNSPipeオブジェクトの書き込み側にプラグインするために使用します。読み取り終了は、パイプからデータを読み取り、テキストビューに追加する GCD ディスパッチ ソースで観察されます。

NSPipe* pipe = [NSPipe pipe];
NSFileHandle* pipeReadHandle = [pipe fileHandleForReading];
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout));
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, [pipeReadHandle fileDescriptor], 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(source, ^{
    void* data = malloc(4096);
    ssize_t readResult = 0;
    do
    {
        errno = 0;
        readResult = read([pipeReadHandle fileDescriptor], data, 4096);
    } while (readResult == -1 && errno == EINTR);
    if (readResult > 0)
    {
        //AppKit UI should only be updated from the main thread
        dispatch_async(dispatch_get_main_queue(),^{
            NSString* stdOutString = [[NSString alloc] initWithBytesNoCopy:data length:readResult encoding:NSUTF8StringEncoding freeWhenDone:YES];
            NSAttributedString* stdOutAttributedString = [[NSAttributedString alloc] initWithString:stdOutString];
            [self.logView.textStorage appendAttributedString:stdOutAttributedString];
        });
    }
    else{free(data);}
});
dispatch_resume(source);

NSLog(@"...")に出力されませんstdoutが - に出力されstderrます。それをテキストビューにリダイレクトする場合は、変更します

dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout));

dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stderr));
于 2013-05-06T09:13:22.953 に答える
-1

目標が、システムが生成したエラー ログではなく、NSLog 出力のみを処理することである場合は、別の方法があります。NSLog をオーバークラスするコードを次に示します。このコードは、通常の NSLog 出力ではなく、stderr にログといくつかの追加情報を出力するだけですが、HyperLog 関数内で必要に応じて変更を加えることができます。

HyperLog.h

#import <Foundation/Foundation.h>

#ifdef HYPER_LOG
#define NSLog(args...) HyperLog(__FILE__,__LINE__,__PRETTY_FUNCTION__,args);
#else
#define NSLog(x...)
#endif

void HyperLog(const char *file, int lineNumber, const char *functionName, NSString *format, ...);

Hyperlog.m

#import "HyperLog.h"

void HyperLog(const char *file, int lineNumber, const char *functionName, NSString *format, ...)
{
    va_list ap;
    va_start (ap, format);
    if (![format hasSuffix: @"\n"])
    {
        format = [format stringByAppendingString: @"\n"];
    }

    NSString *body = [[NSString alloc] initWithFormat:format arguments:ap];
    va_end (ap);
     NSString *fileName = [[NSString stringWithUTF8String:file] lastPathComponent];
    char mesg[8192]="\0";
    NSDate *now =[NSDate date];
    NSString *dateString = [NSDateFormatter localizedStringFromDate:now dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterMediumStyle];
    if ( sprintf( mesg, "<%s.%03.0f> : %s\n<%s : %d - %s>\n", [dateString UTF8String],roundf(fmod( [now timeIntervalSinceReferenceDate], 1 ) * 1000), [body UTF8String], [fileName UTF8String],
                 lineNumber,
            functionName) < 0 ) printf("message creation failed\n");
    fprintf(stderr, "%s", mesg );
}

次に、これらの2行をプログラムファイルの先頭に配置するだけで機能します

#define HYPER_LOG
#import "HyperLog.h"

上記の Thomas のコードを使用して、C 関数を使用してシステム生成エラー ログの結果データをテキスト ファイルに書き込もうとしましたが、他のコンテキストでは正常に動作しますが、クラッシュし続け、エラーの理由が失われます。プロセス。誰もが理由を知っていますか?

于 2016-12-02T13:49:17.283 に答える