项目中如果想把异常捕获再写入文件,有个十分容易使用的库DDLog.
首先导入库,在git上下载。
一:在项目初始化指定全局LogLeve ,一般在xxxapp.m中
staticconstint ddLogLevel = LOG_LEVEL_VERBOSE;
二:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {NSExceptionHandler *exceptionHandler = [NSExceptionHandler defaultExceptionHandler] ;exceptionHandler.delegate = self;exceptionHandler.exceptionHandlingMask = NSLogAndHandleEveryExceptionMask;DBSDDFileLogger *fileLogger = [[DBSDDFileLogger alloc] init];fileLogger.maximumFileSize = 1; // 1024*1 KBfileLogger.rollingFrequency = 1; // 60*60*60 SecondsfileLogger.logFileManager.maximumNumberOfLogFiles = 4;[DDLog addLogger:fileLogger]; }
- (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldLogException:(NSException *)exception mask:(unsigned int)mask {[self printStackTrace:exception];return YES; }
- (void)printStackTrace:(NSException *)e//要写入log文件的信息 {NSString *stack = [[e userInfo] objectForKey:NSStackTraceKey];NSMutableArray *args = [NSMutableArray arrayWithCapacity:20];if (stack) {NSTask *ls = [[NSTask alloc] init];NSString *pid = [[NSNumber numberWithInt:[[NSProcessInfo processInfo] processIdentifier]] stringValue];[args addObject:@"-p"];//-p [args addObject:pid];[args addObjectsFromArray:[stack componentsSeparatedByString:@" "]];// Note: function addresses are separated by double spaces, not a single space.[ls setLaunchPath:@"/usr/bin/atos"];//xcrun atos [ls setArguments:args];// [ls launch];NSPipe *pipe;pipe = [NSPipe pipe];[ls setStandardOutput: pipe];NSFileHandle *file;file = [pipe fileHandleForReading];[ls launch];NSData *data;data = [file readDataToEndOfFile];NSString *string;string = [[NSString alloc] initWithData: dataencoding: NSUTF8StringEncoding];NSString *strFormat = [NSString stringWithFormat:@"\n\n*************************exception begin\nexception time: %@\n%@\n*************************exception end\n\n",[NSDate date] ,string];DDLogCError(strFormat);} else {DDLogCError(@"No stack trace available.");} }
三 。两个自定义类。这里的DBSDDFileLogger继承于DDFileLogger,目的在于自定义log文件的路径。如下:
#import "DBSDDFileLogger.h" #import "DBSDDLogFileManagerDefault.h" #define DBSLogDir @"DBstudio/Files/Logs" @implementation DBSDDFileLogger - (id)init{DBSDDLogFileManagerDefault *defaultLogFileManager = [[DBSDDLogFileManagerDefault alloc] initWithLogsDirectory:[self getDBSCacheLogsDir]];return [self initWithLogFileManager:defaultLogFileManager]; } - (NSString*)getDBSCacheLogsDir{NSString *dir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0];NSString *cachedLogDir=[dir stringByAppendingPathComponent:DBSLogDir];return cachedLogDir; }
DBSDDLogFileManagerDefault 继承自 DDLogFileManagerDefault 目的在于自定义log文件的路径
@implementation DBSDDLogFileManagerDefault - (NSString *)generateShortUUID{NSDate *date = [[NSDate alloc] init];NSDateFormatter *threadUnsafeDateFormatter = [[NSDateFormatter alloc] init];[threadUnsafeDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];NSString *dateFormatString = @"yyyy-MM-dd";[threadUnsafeDateFormatter setDateFormat:dateFormatString];NSString *filename = [threadUnsafeDateFormatter stringFromDate:date];return filename; } - (NSString *)createNewLogFile{NSString *logsDirectory = [self logsDirectory];int index = 1;NSString *fileName = [NSString stringWithFormat:@"dbs-log-%@.txt", [self generateShortUUID]];do{NSString *filePath = [logsDirectory stringByAppendingPathComponent:fileName];if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]){[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];// Since we just created a new log file, we may need to delete some old log files [super deleteOldLogFiles];NSLog(@"create file:%@",fileName);return filePath;}else{NSString *strFile = [filePath stringByDeletingPathExtension];NSString *strFileName = [strFile lastPathComponent];NSString *strFileNameFormat = [self isContainCharacter:strFileName];if (strFileNameFormat) {strFileName = strFileNameFormat;}fileName =[NSString stringWithFormat:@"%@(%d).%@",strFileName,index,[filePath pathExtension]];index++;}} while(YES); }- (NSString*)isContainCharacter:(NSString*)fileName{NSString *strCharachter = @"(";NSRange foundPer=[fileName rangeOfString:strCharachter options:NSCaseInsensitiveSearch];if(foundPer.length>0) {NSRange rang;rang.location = 0;rang.length = foundPer.location;NSString *strRes = [fileName substringWithRange:rang];return strRes;}else {return nil;} }- (BOOL)isLogFile:(NSString *)fileName{if (fileName && [fileName length]>3) {NSRange rang;rang.location = [fileName length] - 4;rang.length = 4;NSString *strTmpName = [fileName substringWithRange:rang];if ([strTmpName isEqualToString:@".txt"]) {rang.location = 0;rang.length = 4;strTmpName = [fileName substringWithRange:rang];if ([@"dbs-" isEqualToString:strTmpName]) {return YES;}}}return NO; }
好了,test一下
- (IBAction)test:(id)sender {//@try {NSMutableArray *array = [NSMutableArray array];[array addObject:nil];//}//@catch (NSException *exception) {//@throw exception;//}//@finally {//} }
