NSLog 重定向
不在控制台输出,而是定向到指定的地方统一处理。
为什么要对NSLog重定向
在开发中,我可能需要对日记保存,但在NSLog调用地方都调用保存操作,很不方便也不方便维护;当然你也可以使用第三方框架(比如CocoaLumberjack),但是你可能仅仅想保存日记这个操作,而不需要其他操作,并不想使用第三方框架,这时对NSLog重定向是一个很好的选择(毕竟习惯了NSLog)。
代码实现
我已封装成一个工具类,可以拿去使用。
Objective-C 版本
NSLogRedirect.h 代码
#import <Foundation/Foundation.h>
@interface NSLogRedirect : NSObject
+ (void)enableRedirect;
@end
NSLogRedirect.m 代码
#import "NSLogRedirect.h"
@implementation NSLogRedirect
/**
在 application:didFinishLaunchingWithOptions: 方法中最先调用此方法即可对NSLog重定向
*/
+ (void)enableRedirect {
static NSLogRedirect *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[NSLogRedirect alloc] init];
});
}
- (instancetype)init
{
self = [super init];
if (self) {
[self redirectToPostNotification:STDERR_FILENO];
}
return self;
}
- (void)redirectToPostNotification:(int)fileno {
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *pipeReadHandle = [pipe fileHandleForReading];
int pipeFileHandle = [[pipe fileHandleForWriting] fileDescriptor];
dup2(pipeFileHandle, fileno);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(redirectNotificationHandle:)
name:NSFileHandleReadCompletionNotification
object:pipeReadHandle];
[pipeReadHandle readInBackgroundAndNotify];
}
- (void)redirectNotificationHandle:(NSNotification *)notification {
/** ==== 请不要在此函数中使用NSLog ====*/
/** ==== 请不要在此函数中使用NSLog ====*/
/** ==== 请不要在此函数中使用NSLog ====*/
/** ==== 会导致死循环,会导致死循环,会导致死循环 ====*/
NSData *data = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
NSString *messageString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSArray<NSString *> *messages = [messageString componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"\n]"]];
for (NSString *messageItem in messages) {
if (!messageItem.length || [messageItem containsString:@"["]) {
continue;
}
// 在此处理每一条log,messageItem为log的内容
/** 比如:统一保存到指定文件中 */
/** 比如:统一输出格式,使用printf打印出来 */
/** ........... */
printf("%s\n", messageItem.UTF8String);
}
[[notification object] readInBackgroundAndNotify];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
Swift 版本
comeing soon
还不快抢沙发