Ответ 1
Используйте printf()
вместо NSLog()
Имеются ли в NSLog() варианты, которые печатаются без отметки времени и даты, и автоматической новой строки?
Спасибо. Теперь со следующим кодом я могу напечатать NSString, cString или объекты:
#import <Foundation/Foundation.h>
#import <stdio.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *s = @"Hello, World!";
NSDate *today = [NSDate date];
NSLog(@"%@", s);
printf("%s at %s", [s UTF8String], [[today description] UTF8String]);
[pool drain];
return 0;
}
Используйте printf()
вместо NSLog()
Это тоже меня беспокоило, поэтому я написал функцию для замены NSLog()
и printf()
:
void IFPrint (NSString *format, ...) {
va_list args;
va_start(args, format);
fputs([[[[NSString alloc] initWithFormat:format arguments:args] autorelease] UTF8String], stdout);
va_end(args);
}
Затем вы можете просто использовать его вместо NSLog()
(например, IFPrint(@"Current date: %@", [NSDate date])
), но он не будет печатать какие-либо отметки времени или новую строку, и вам не нужно возиться со строками и массивами C, и что "нет. Я бы сказал, это очень удобно.
Если вы хотите, посмотрите мой полный код (я также написал замену fprintf, scanf и fscanf) здесь.
(Там также есть тема о нем здесь).
Этот код будет работать
#ifdef DEBUG
#define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
#define NSLog(...) {}
#endif
Мне нравится решение Itai. Я просто изменил код, чтобы использовать CFShow в среде ARC.
void CFLog(NSString *format, ...)
{
va_list args;
va_start(args, format);
CFShow((__bridge CFStringRef)[[NSString alloc] initWithFormat:format arguments:args]);
va_end(args);
}
ПЕРВАЯ вещь, которую я делаю в ЛЮБОМ проекте, падает (моя сокращенная версия) этот класс..., который избавляется от ВСЕХ NONSENSE в NSLog
... Поместите это вверху файла .m
, и ваш вывод консоли будет PERFECT.
#import <Foundation/Foundation.h>
#import <stdio.h>
#define MLogString(s,...) \
[MLog logFile:__FILE__ lineNumber:__LINE__ \
format:(s),##__VA_ARGS__]
@interface MLog : NSObject { }
+ (void) logFile: (char*) sourceFile lineNumber: (int) lineNumber format: (NSString*) format, ...;
+ (void) setLogOn: (BOOL) logOn;
@end
#ifndef NDEBUG
extern void _NSSetLogCStringFunction(void (*)(const char *string, unsigned length, BOOL withSyslogBanner));
static void PrintNSLogMessage(const char *string, unsigned length, BOOL withSyslogBanner){ puts(string); }
static void HackNSLog(void) __attribute__((constructor));
static void HackNSLog(void){ _NSSetLogCStringFunction(PrintNSLogMessage); }
#endif
static BOOL __MLogOn = NO;
@implementation MLog
+ (void) initialize { char * env = getenv("MLogOn");
if (strcmp(env == NULL ? "" : env, "NO") != 0) __MLogOn = YES;
}
+ (void) logFile: (char *) sourceFile lineNumber: (int) lineNumber format: (NSString *) format, ...; {
va_list ap; NSString *print, *file;
if (__MLogOn == NO) return; va_start(ap, format);
file = [[NSString alloc] initWithBytes: sourceFile length:strlen(sourceFile) encoding: NSUTF8StringEncoding];
print = [[NSString alloc] initWithFormat:format arguments: ap];
va_end(ap); // NSLog handles synchronization issues
NSLog(@"%s: %d %@", [[file lastPathComponent] UTF8String], lineNumber, print); return;
}
+ (void) setLogOn: (BOOL) logOn { __MLogOn = logOn; }
@end
Определите макрос
#if __has_feature(objc_arc)
#define DLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]);
#else
#define DLog(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
#endif
И используйте этот макрос в вашем коде, например
NSLog(@"Content with time stamp");
DLog(@"Content without time stamp");
Вот вывод консоли
NSLog → 2014-01-28 10:43:17.873 TestApp[452:60b] Content with time stamp
DLog → Content without time stamp
Если кому-то нужны пользовательские журналы, которые дают вам больше информации, например, имя метода/номер строки и т.д., можно загрузить исходный код MLog.h on GitHub
.