如何处理Objective-C库中的日志?
发布时间:2020-12-16 04:59:14 所属栏目:百科 来源:网络整理
导读:我正在写一个Objective-C库,在某些地方我想记录一些信息.使用NSLog并不理想,因为它不可配置,既没有级别支持也不支持标签. CocoaLumberjack和NSLogger都是支持级别和上下文/标签的受欢迎的日志库,但我不希望依赖于第三方日志记录库. 如何以可配置的方式生成日
我正在写一个Objective-C库,在某些地方我想记录一些信息.使用NSLog并不理想,因为它不可配置,既没有级别支持也不支持标签.
CocoaLumberjack和NSLogger都是支持级别和上下文/标签的受欢迎的日志库,但我不希望依赖于第三方日志记录库.
如何以可配置的方式生成日志,不会强制我的用户使用特定的日志库? 解决方法
TL; DR在您的API中显示日志处理程序块.
这是一个建议,使用记录器类作为公共API的一部分,使日志配置非常容易.让我们称之为MYLibraryLogger: // MYLibraryLogger.h #import <Foundation/Foundation.h> typedef NS_ENUM(NSUInteger,MYLogLevel) { MYLogLevelError = 0,MYLogLevelWarning = 1,MYLogLevelInfo = 2,MYLogLevelDebug = 3,MYLogLevelVerbose = 4,}; @interface MYLibraryLogger : NSObject + (void) setLogHandler:(void (^)(NSString * (^message)(void),MYLogLevel level,const char *file,const char *function,NSUInteger line))logHandler; @end 这个类有一个方法,允许客户端注册日志处理程序块.这使得客户端可以使用他们喜欢的库来实现日志记录.以下是客户端将如何使用NSLogger: [MYLibraryLogger setLogHandler:^(NSString * (^message)(void),NSUInteger line) { LogMessageRawF(file,(int)line,function,@"MYLibrary",(int)level,message()); }]; 或与CocoaLumberjack: [MYLibraryLogger setLogHandler:^(NSString * (^message)(void),NSUInteger line) { // The `MYLogLevel` enum matches the `DDLogFlag` options from DDLog.h when shifted [DDLog log:YES message:message() level:ddLogLevel flag:(1 << level) context:MYLibraryLumberjackContext file:file function:function line:line tag:nil]; }]; 这是MYLibraryLogger的一个实现,它具有仅记录错误和警告的默认日志处理程序: // MYLibraryLogger.m #import "MYLibraryLogger.h" static void (^LogHandler)(NSString * (^)(void),MYLogLevel,const char *,NSUInteger) = ^(NSString *(^message)(void),NSUInteger line) { if (level == MYLogLevelError || level == MYLogLevelWarning) NSLog(@"[MYLibrary] %@",message()); }; @implementation MYLibraryLogger + (void) setLogHandler:(void (^)(NSString * (^message)(void),NSUInteger line))logHandler { LogHandler = logHandler; } + (void) logMessage:(NSString * (^)(void))message level:(MYLogLevel)level file:(const char *)file function:(const char *)function line:(NSUInteger)line { if (LogHandler) LogHandler(message,level,file,line); } @end 这个解决方案的最后一个缺失的部分是一组宏,供您通过库使用. // MYLibraryLogger+Private.h #import <Foundation/Foundation.h> #import "MYLibraryLogger.h" @interface MYLibraryLogger () + (void) logMessage:(NSString * (^)(void))message level:(MYLogLevel)level file:(const char *)file function:(const char *)function line:(NSUInteger)line; @end #define MYLibraryLog(_level,_message) [MYLibraryLogger logMessage:(_message) level:(_level) file:__FILE__ function:__PRETTY_FUNCTION__ line:__LINE__] #define MYLibraryLogError(format,...) MYLibraryLog(MYLogLevelError,(^{ return [NSString stringWithFormat:(format),##__VA_ARGS__]; })) #define MYLibraryLogWarning(format,...) MYLibraryLog(MYLogLevelWarning,##__VA_ARGS__]; })) #define MYLibraryLogInfo(format,...) MYLibraryLog(MYLogLevelInfo,##__VA_ARGS__]; })) #define MYLibraryLogDebug(format,...) MYLibraryLog(MYLogLevelDebug,##__VA_ARGS__]; })) #define MYLibraryLogVerbose(format,...) MYLibraryLog(MYLogLevelVerbose,##__VA_ARGS__]; })) 那么你只需在你的库中使用它: MYLibraryLogError(@"Operation finished with error: %@",error); 请注意日志消息是如何返回字符串而不是字符串的块.这样,如果定义的日志处理程序决定不评估消息(例如,基于上述默认日志处理程序中的日志级别),则可以避免昂贵的计算.这样,如果日志被丢弃,您可以编写具有潜在昂贵的日志消息的单行日志进行计算,而不会导致性能下降,例如: MYLibraryLogDebug(@"Object: %@",^{ return object.debugDescription; }()); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |