关于重定向stderr到文件 NSLog

转:关于重定向stderr到文件 NSLog

转: http://www.cocoachina.com/bbs/read.php?tid-39344.html

[自:我在iOS4.2 Debug和Relase版本的模拟器上的试验结果是:
使用NSLog的话,即使不使用fflush(stderr),也会立刻更新到文件中的。
使用fprintf(stderr, "hello\n");的话,默认不会立刻更新到文件中。
但是如果调用fflush(stderr),则会立刻更新到文件中。这一点跟楼主的试验结果不同啊。会不会是iOS的版本不同导致的。 ]

你可能会碰到某些情况下你无法用xcode进行调试,或者用GDB查看NSLog的输出,比如你正在为某个外部附件 开发 应用程序。
没有Log是对于 定位和查找bug都是非常困难的,好在我们可以通过重定向,将标准的 错误输出stderr定向到文件。
这里我只是 分享给大家一些调试的经验和方法。请大大们轻拍。

NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [paths objectAtIndex:0];
NSString *logPath = [documentDir stringByAppendingPathComponent:@"decrypt.log"];
freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "w+", stderr);

让我们看下这段 代码,它的作用就是在程序内部的文件夹Documents中新建一个名为decrypt.log的文件,并且将所有的stderr输入到decrypt.log
文件中。如此一来所有关于stderr的输出都将被重定向到decrypt.log,在gdb中你将无法再看到这些信息。

关于 使用
下面来说说如何查看这个文件(可能很多同学都会了)
1、xcode->Windows->Organizer
2、找到你的设备,在summary一栏中找到你的程序,将其展开,点选右边那个小箭头,这样程序内部的所有文件夹都将导出到你所指定的位置。
3、还是Organizer左边一栏的PROJECTS&SOURCES展开便能找到


关于 printf, fprintf 和NSLog:
可能你大量使用了外部的c库,它们以printf或者fprintf来输出信息 ,那么它们的区别又是什么?
标准的printf它是将调试信息 输入到标准输出流stdout,也就是说你用上面提供的函数是无法将此重定向的,你必须
reopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "w+", stdout);
而fprintf则可以指定你所要输出的调试信息的位置,包括stdout、stderr甚至是一般的文件。
这里我们输出到stderr
fprintf(stderr, "hello\n");

NSLog它本质上其实也是将调试信息输出到stderr(并不确定?),但与fprintf不同它还有些不一样的特性。

我们在使用xcode进行调试的时候无论采用哪种方式输出错误信息总是第一时间刷新在屏幕上,但定向到文件却有所不同,
NSLog总是能第一时间写到文件,而printf或者fprintf它们似乎将是信息保存在缓存中,等待某种契机或者信号才会将
信息写到文件中如此一来辛苦准备的调试信息却可能因为程序的崩溃而什么也无法看到。
所以我们可以通过fflush来强制它进行刷新。如下,我们强制刷新stderr
fflush(stderr)

但是这里我有一个疑问,想请各位高手指教,我实验中我发现NSLog确实应该是stderr的输出流,那么按照我上面所说的,
为了保证信息的即时输出,它应该内部调用了fflush(stderr)才对,但是如果是fflush(stderr)的话,那么之前的stderr上的信息应该也是
一起输出的,但结果却是只有NSLog的信息得到了输出,原本stderr中的信息依旧保存在缓存中,不知道NSLog到底做了
些什么。。。

最后给大家两个调试用的宏(可能各位也早已知道)
__FILE__ 分别是所在的文件 (字符串)
__LINE__ 和行号(数字)
希望对大家有所帮助
+++++
 

 

你可能感兴趣的:(职场,休闲,nslog,定向)