아무도 Stdout을 NSTextView로 리디렉션하는 방법을 보여줄 수 있습니까?STDOUT을 NSTextView로 리디렉션하는 방법은 무엇입니까?
그리고 NSLog의 정보 인쇄가 std?
감사
는아무도 Stdout을 NSTextView로 리디렉션하는 방법을 보여줄 수 있습니까?STDOUT을 NSTextView로 리디렉션하는 방법은 무엇입니까?
그리고 NSLog의 정보 인쇄가 std?
감사
는코드는 아래 NSPipe
오브젝트의 추 단부에 표준 출력 플러그 dup2
를 이용한다. 읽기 끝은 파이프에서 데이터를 읽어 텍스트 뷰에 추가하는 GCD 디스패치 소스에서 관찰됩니다.
NSPipe* pipe = [NSPipe pipe];
NSFileHandle* pipeReadHandle = [pipe fileHandleForReading];
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout));
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
에 인쇄합니다. 당신이 당신의 텍스트 뷰에 그 리디렉션하려면 목표 만 NSLog 출력이 아닌 시스템에서 생성되는 오류 로그를 처리하는 경우, 다른 방식이,
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout));
에
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stderr));
변경 그렇다면 여기 NSLog를 오버 클래 싱하는 코드가 있습니다. 이 코드는 로그 대신 일반적인 NSLog 출력의 표준 오류에 대한 몇 가지 추가 정보를 인쇄하는,하지만 당신은의 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);
}
당신 만 프로그램 파일의 맨 위에 다음이 줄을 둘 필요가 가 작동해야합니다
#define HYPER_LOG
#import "HyperLog.h"
위의 코드를 토마스에서 사용하여 시스템의 결과 데이터를 생성하려고 시도했지만 오류 로그를 C 함수를 사용하여 텍스트 파일에 작성했습니다. 다른 문맥에서는 제대로 작동하지만 유지 및 충돌 및 오류 이유가 과정에서 없어집니다. 누구나 이유가 무엇입니까?
이것은 바보 같은 질문 일 수 있습니다 : NSPipe가 이미 버퍼링되었거나 (자체 구현에 의해 또는 다른 방법으로 랩핑 된 OS 구조에 의해) 버퍼링 된 경우 자체 데이터 버퍼를 정의해야하는 이유는 무엇입니까? – algal
NSPipe가 기본적으로 버퍼링됩니다 ("파이프가 버퍼 됨, 버퍼의 크기는 기본 운영 체제에 의해 결정됩니다 ..."). 그러나 청크를 읽고, 자신의 프로세스 내에서 메모리 소비에 대해 세분화 된 제어를하는 것이 여전히 좋은 생각 일 수 있습니다. (파이프의 버퍼가 OS에 의해 유지되는 것처럼 들립니다.) –
또한 'do' 루프가 이러한 조건이없는 오류나 종료 조건을 잘못 테스트 할 수 있습니까? – algal