• iOS


    转:http://blog.csdn.net/marujunyy/article/details/12005767

    对于真机,日志没法保存,不好分析问题。所以有必要将日志保存到应用的Docunment目录下,方便取出分析。


    首先是日志输出,分为c的printf和标准的NSLog输出,printf会向标准输出(sedout)打印,而NSLog则是向标准出错(stderr),我们需要同时让他们都将日志打印到一个文件中。 其次是Crash问题;Crash分为两种,一种是由EXC_BAD_ACCESS引起的,原因是访问了不属于本进程的内存地址,有可能是访问已被释放的内存;另一种是未被捕获的Objective-C异常(NSException),导致程序向自身发送了SIGABRT信号而崩溃。其实对于未捕获的Objective-C异常,我们是有办法将它记录下来的,如果日志记录得当,能够解决绝大部分崩溃的问题。


    我写了两个函数用于写NSLog日志和Crash日志,这个两个函数都必须在AppDelegate文件中下面的函数里添加

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    1. //连接xcode时可以从监视器中看日志 没连接时Log日志会输出到文件中,  
    2. [self redirectNSLogToDocumentFolder];  
    1. - (void)redirectNSLogToDocumentFolder  
    2. {  
    3.     //如果已经连接Xcode调试则不输出到文件  
    4.     if(isatty(STDOUT_FILENO)) {  
    5.         return;  
    6.     }  
    7.       
    8.     UIDevice *device = [UIDevice currentDevice];  
    9.     if([[device model] hasSuffix:@"Simulator"]){ //在模拟器不保存到文件中  
    10.         return;  
    11.     }  
    12.       
    13.     //将NSlog打印信息保存到Document目录下的Log文件夹下  
    14.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
    15.     NSString *logDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Log"];  
    16.       
    17.     NSFileManager *fileManager = [NSFileManager defaultManager];  
    18.     BOOL fileExists = [fileManager fileExistsAtPath:logDirectory];  
    19.     if (!fileExists) {  
    20.         [fileManager createDirectoryAtPath:logDirectory  withIntermediateDirectories:YES attributes:nil error:nil];  
    21.     }  
    22.       
    23.     NSDateFormatter *formatter = [[NSDateFormatter alloc] init];  
    24.     [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];  
    25.     [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; //每次启动后都保存一个新的日志文件中  
    26.     NSString *dateStr = [formatter stringFromDate:[NSDate date]];  
    27.     NSString *logFilePath = [logDirectory stringByAppendingFormat:@"/%@.log",dateStr];  
    28.       
    29.     // 将log输入到文件  
    30.     freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);  
    31.     freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);  
    32.       
    33.     //未捕获的Objective-C异常日志  
    34.     NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler);  
    35. }  
    36.   
    37. void UncaughtExceptionHandler(NSException* exception)  
    38. {  
    39.     NSString* name = [ exception name ];  
    40.     NSString* reason = [ exception reason ];  
    41.     NSArray* symbols = [ exception callStackSymbols ]; // 异常发生时的调用栈  
    42.     NSMutableString* strSymbols = [ [ NSMutableString alloc ] init ]; //将调用栈拼成输出日志的字符串  
    43.     for ( NSString* item in symbols )  
    44.     {  
    45.         [ strSymbols appendString: item ];  
    46.         [ strSymbols appendString: @" " ];  
    47.     }  
    48.       
    49.     //将crash日志保存到Document目录下的Log文件夹下  
    50.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
    51.     NSString *logDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Log"];  
    52.       
    53.     NSFileManager *fileManager = [NSFileManager defaultManager];  
    54.     if (![fileManager fileExistsAtPath:logDirectory]) {  
    55.         [fileManager createDirectoryAtPath:logDirectory  withIntermediateDirectories:YES attributes:nil error:nil];  
    56.     }  
    57.       
    58.     NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.log"];  
    59.     NSDateFormatter *formatter = [[NSDateFormatter alloc] init];  
    60.     [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];  
    61.     [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];  
    62.     NSString *dateStr = [formatter stringFromDate:[NSDate date]];  
    63.       
    64.     NSString *crashString = [NSString stringWithFormat:@"<- %@ ->[ Uncaught Exception ] Name: %@, Reason: %@ [ Fe Symbols Start ] %@[ Fe Symbols End ] ", dateStr, name, reason, strSymbols];  
    65.     //把错误日志写到文件中  
    66.     if (![fileManager fileExistsAtPath:logFilePath]) {  
    67.         [crashString writeToFile:logFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];  
    68.     }else{  
    69.         NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:logFilePath];  
    70.         [outFile seekToEndOfFile];  
    71.         [outFile writeData:[crashString dataUsingEncoding:NSUTF8StringEncoding]];  
    72.         [outFile closeFile];  
    73.     }  
    74.       
    75.     //把错误日志发送到邮箱  
    76.     //    NSString *urlStr = [NSString stringWithFormat:@"mailto://test@163.com?subject=bug报告&body=感谢您的配合!<br><br><br&gt;错误详情:<br>%@",crashString ];  
    77.     //    NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];  
    78.     //    [[UIApplication sharedApplication] openURL:url];  
    79. }  


  • 相关阅读:
    HashMap实现分析
    序列化与transient
    MySQL计划任务(事件调度器)(Event Scheduler)[转]
    利用innodb_force_recovery修复MySQL数据页损坏
    Java对Jar文件的操作[转]
    聚集索引与非聚集索引
    JVM学习(二)
    一句道破所有的springmvc(面试必备)
    springboot中的外界jar的引入:
    springboot中的springSession的存储和获取
  • 原文地址:https://www.cnblogs.com/jackljf/p/4768601.html
Copyright © 2020-2023  润新知