我们的解决方案取决于两个问题:
- 我们是否使用 Xcode 8 及更高版本进行编译?如果是,则识别出新的 os_log。如果没有,我们必须回退到现有的 NSLog 行为。
- 我们是否在 iOS-10 及更高版本下运行?如果是,我们可以使用新的记录器。如果没有,我们必须回退到现有的 NSLog 行为。
我们将找到关于编译时间的问题 [1] 的答案。对于 [2],我们必须在运行时进行测试。
这里是实现:
mylog.h
//only used to force its +load() on app initialization
@interface MyLog:NSObject
@end
#if !__has_builtin(__builtin_os_log_format)
//pre Xcode 8. use NSLog
#else
//we need this include:
#import <os/log.h>
#endif
void myLog(NSString *format, ...);
#ifdef DEBUG
#define NSLog(f, ...) myLog(f, ## __VA_ARGS__)
#else
#define NSLog(f, ...) (void)0
#endif
mylog.m
@implementation MyLog
BOOL g_useNewLogger = NO;
+(void)load
{
NSOperatingSystemVersion os_ver = [[NSProcessInfo processInfo] operatingSystemVersion];
if (os_ver.majorVersion >= 10) {
g_useNewLogger = YES;
}
NSLog(@"Use new logger: %@", g_useNewLogger? @"YES":@"NO");
}
@end
void myLog(NSString *format, ...)
{
va_list args;
va_start(args, format);
#if !__has_builtin(__builtin_os_log_format)
//pre Xcode 8. use NSLog
NSLogv(format, args);
#else
//Xcode 8 and up
if (g_useNewLogger) { // >= iOS 10
NSString *nsstr = [[NSString alloc] initWithFormat:format arguments:args];
os_log(OS_LOG_DEFAULT, "%{public}s", [nsstr cStringUsingEncoding:NSUTF8StringEncoding]);
} else { // < iOS 10
NSLogv(format, args);
}
#endif
va_end(args);
}