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

iOS - NSLog、UncaughtException日志保存到文件的更多相关文章

  1. 【代码笔记】iOS-将log日志保存到文件

    代码: #import "AppDelegate.h" #import "RootViewController.h" @implementation AppDe ...

  2. logstash自己的日志保存到文件中:log4j2.properties

    status = error dest = err name = PropertiesConfig property.filename = /gwlog/data/logstash/logs appe ...

  3. C# log4net 配置及使用详解--日志保存到文件和Access(转)

    按语: 最近项目要求选用Access数据库,但日志管理采用log4net,但保存到数据库一直没有成功,后按照如下配置在程序退出时可以成功保存. 开始新建文件应用log4net.dll  ,重新编译就报 ...

  4. ios NSLog常见使用

    NSLog常见输出格式 Table 1  Format specifiers supported by the NSString formatting methods and CFString for ...

  5. 如何将Log4Net 日志保存到mongodb数据库之实践

    log4net的大名早有耳闻,一直没真正用过,这次开发APP项目准备在服务端使用log4net. 日志的数据量较大,频繁的写数据库容易影响系统整体性能,所以独立将日志写到mongodb数据库是不错的选 ...

  6. iOS - NSLog的使用方法

    NSLog的定义 NSLog定义在NSObjCRuntime.h中,如下所示: void NSLog(NSString *format, …); 基本上,NSLog很像printf,同样会在conso ...

  7. IOS NSLog 打印bool值

    输出BOOL值的方法:NSLog(@"%@",YES?@"YES":@"NO");%@输出字符串. NSLog(@"ifReadO ...

  8. iOS NSLog去掉时间戳及其他输出样式

    1.一般项目中我的NSLog会在Prefix.pch文件添加如下代码,已保证在非调试状态下NSLog不工作   1 2 3 4 5 #ifdef DEBUG #define NSLog(...) NS ...

  9. iOS NSLog各种打印

    %@ 对象 %d,%i 整型 (%i的老写法) %hd 短整型 %ld , %lld 长整型 %u 无符整型 %f 浮点型和double型 %0.2f 精度浮点数,只保留两位小数 %x:    为32 ...

随机推荐

  1. OpenLDAP配置信息记录

    随着各种研发工具使用越来越多,单独为每个工具维护一个账号系统的开销越来越大,而且作为用户多个账号密码使用也越来越不方便.所以需要做一个统一账号登陆. 查询了多个方法,又因为之前用过LDAP,所以选择了 ...

  2. Asp.net MVC4.0自定义Html辅助方法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  3. Servlet 各种path路径比较

    假定你的web application 名称为news,你在浏览器中输入请求路径: http://localhost:8080/news/main/list.jsp 则执行下面向行代码后打印出如下结果 ...

  4. 黑马程序员-- .net基础加强8之委托,事件,程序集

    ---------------------- ASP.Net+Android+IOS开发..Net培训.期待与您交流! ---------------------- 一.委托 ============ ...

  5. java.lang.NoClassDefFoundError: JspException

    在打开jsp页面的时候报错java.lang.NoClassDefFoundError: JspException,如下所示: 原因和解决方案: 原因是由于包不全 把该导的包导进去,在上面的例子就是由 ...

  6. 查看mininet交换机中的流表

    官网文档http://mininet.org/walkthrough/#xterm-display Xterms are also useful for running interactive com ...

  7. 李洪强漫谈iOS开发[C语言-037]-if else 语句

    李洪强漫谈iOS开发[C语言-037]-if else 语句

  8. lintcode:Singleton 单例

    题目: 单例 单例是最为最常见的设计模式之一.对于任何时刻,如果某个类只存在且最多存在一个具体的实例,那么我们称这种设计模式为单例.例如,对于 class Mouse (不是动物的mouse哦),我们 ...

  9. 【memcache缓存专题(3)】PHP-memcache扩展的安装以及使用

    安装PHP-memcache扩展和安装其他PHP扩展的步骤是一样的. 安装 step 1:搜索下载扩展 http://pecl.php.net/package/memcache step 2: gzi ...

  10. java小程序:求完全数

    如果一个数等于它的不包括自身的所有因数之和,那么这个数就叫完全数.例如,6的不包括自身的所有因数为1,2,3,而且6=1+2+3,所以6是完全数. 大约2200多年前,欧几里德提出:如果2n-1是质数 ...