Czy ktoś może mi pokazać, jak przekierować Stdout do NSTextView?Jak przekierować STDOUT do NSTextView?
i czy informacje wydrukowane przez NSLog należą do standardu?
Dzięki
Czy ktoś może mi pokazać, jak przekierować Stdout do NSTextView?Jak przekierować STDOUT do NSTextView?
i czy informacje wydrukowane przez NSLog należą do standardu?
Dzięki
Poniższy kod wykorzystuje dup2
podłączyć stdout na koniec zapisu obiektu NSPipe
. Read-end jest obserwowany ze źródłem wysyłki GCD, które odczytuje dane z potoku i dołącza je do widoku tekstowego.
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(@"...")
nie wyjście do stdout
chociaż - Drukuje do stderr
. Jeśli chcesz przekierować że w swojej TextView zmień
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout));
do
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stderr));
jeśli celem jest, aby obsłużyć tylko swoje wyjście NSLog, a nie system wygenerował dzienników błędów, nie ma innego sposobu, aby zrób tak, tutaj jest kod do przełożenia NSLog. Ten kod jest drukowanie tylko dziennik i kilka dodatkowych informacji na stderr zamiast zwykłego wyjścia NSLog, ale można dokonywać żadnych zmian, które Apartamenty swoich potrzeb wewnątrz funkcji 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);
}
następnie wystarczy umieścić te 2 linie na górze dowolnego pliku programu mają działać
#define HYPER_LOG
#import "HyperLog.h"
Próbowałem użyć powyższego kodu z Thomasa, aby uzyskać dane wynikowe wygenerowanego przez system dziennika błędów zapisanego w pliku tekstowym za pomocą funkcji C, która działa poprawnie w innych kontekstach, ale zachowuje się i ulega awarii, a błąd powód jest tracony w procesie. Ktoś ma pomysł, dlaczego?
To może być głupie pytanie, ale: jeśli NSPipe jest już zbuforowane (przez własną implementację lub przez konstrukcję OS, którą się opakowuje), to dlaczego konieczne jest zdefiniowanie własnego bufora danych? – algal
Masz rację NSPipe jest domyślnie buforowana (z dokumentacji "... rura jest buforowana, rozmiar bufora jest określany przez system operacyjny ..."). Ale nadal dobrym pomysłem jest czytanie fragmentów, aby mieć dokładniejszą kontrolę nad zużyciem pamięci w ramach własnego procesu. (Wygląda na to, że bufor rury jest utrzymywany przez system operacyjny). –
Czy jest też możliwe, że pętla 'do' nieprawidłowo testuje błędy lub warunki zakończenia zamiast braku tych warunków? – algal