Customize NSLog for Easier Debugging
来源:互联网 发布:学java月薪多少 编辑:程序博客网 时间:2024/06/14 11:15
http://hub.tutsplus.com/tutorials/customize-nslog-for-easier-debugging--mobile-19066
In this quick tip we are going to learn how to customize the output generated by NSLog in order to debug programs more efficiently. Read on!
Problem
By default, NSLog displays output in the following format:
Date Time OurApp[<processid>] NSLog output
A real-world example might look like this:
20130803 00:35:53.038 TestApp[460:c07] Value of result = 20
The default output is good, but it leaves something to be desired. Most of the time, we want to see the following in a log statement:
- Name of the source file where NSLog() was called
- Source code line number where NSLog() was called
- Name of the class and method where NSLog() was called
- Hide date time stamp, application name, and process id info
- Enable/disable log information by changing mode (e.g. debug, release, staging)
In short, we would like NSLog to be more like this:
(ClassName MethodName) (SourceFileName:LineNumber) NSLog output
Solution
Let's first look at how NSLog works unaltered. NSLog is just a C function built into the foundation framework of Cocoa, and behaves just like any othervariadic C function. Specifically, NSLog sends error messages to the Apple System Log facility. It does this simply by passing its arguments along to theNSLogv function.
Because NSLog is just a wrapper for NSLogv, we can redefine NSLog with our own custom call to NSLogv. That is exactly what I will show you how to do in this tutorial.
1. Start a New Project
Create a new iOS project in Xcode, with the Empty Application template. Call it ExtendNSLog. Check the option for Automatic Reference Counting, but uncheck the options for Core Data and Unit Tests.
Create An iOS project with the Empty Application templateProduct name should be "ExtendNSLog"2. Create an Objective-C Class
Now create a header file along with the project. Select New File > Objective-C Class. Set the name of the class to ExtendNSLogFunctionality. which will be a subclass of NSObject.
Create an Objective-C class templateSet the class name to ExtendNSLogFunctionality3. Add Custom NSLog Logic
Step 1
Open ExtendNSLogFunctionality.h and place the following code within the header:
#import <Foundation/Foundation.h>
#ifdef DEBUG
#define NSLog(args...) ExtendNSLog(__FILE__,__LINE__,__PRETTY_FUNCTION__,args);
#else
#define NSLog(x...)
#endif
void ExtendNSLog(const char *file, int lineNumber, const char *functionName, NSString *format, ...);
The above conditional will define an NSLog
statement only when DEBUG is defined. When DEBUG is not defined, the NSLog statement will do nothing. The question arises: how do you control when DEBUG is defined? This can be done by assigning DEBUG=1 in the preprocessor settings for your project.
To do so, click on your application target, and select the Build Settings tab. Next make sure that the "All" and "Combined" options are selected. Search for "preprocessing" and locate the section titled "Preprocessor Macros". Next, simply add "DEBUG=1" to the Debug section.
Add the DEBUG=1 flag to the preprocessor settingsNote that in more recent Xcode project templates, there will already be a DEBUG=1 macro defined for the Debug build configuration in the Preprocessor Macros section. For more information, refer to this post on StackOverflow.
Step 2
With the debug macro defined, our next task is to write the custom version of NSLog. Open ExtendNSLogFunctionality.m and add the following code:
#import "ExtendNSLogFunctionality.h"void ExtendNSLog(const char *file, int lineNumber, const char *functionName, NSString *format, ...){ // Type to hold information about variable arguments. va_list ap; // Initialize a variable argument list. va_start (ap, format); // NSLog only adds a newline to the end of the NSLog format if // one is not already there. // Here we are utilizing this feature of NSLog() if (![format hasSuffix: @"\n"]) { format = [format stringByAppendingString: @"\n"]; } NSString *body = [[NSString alloc] initWithFormat:format arguments:ap]; // End using variable argument list. va_end (ap); NSString *fileName = [[NSString stringWithUTF8String:file] lastPathComponent]; fprintf(stderr, "(%s) (%s:%d) %s", functionName, [fileName UTF8String], lineNumber, [body UTF8String]);}
Step 3
Now add the ExtendNSLogFunctionality.h include to the prefix header file Prefix.pch within the #ifdef __OBJC__ section.
#ifdef __OBJC__ #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #import "ExtendNSLogFunctionality.h"#endif
For a better understanding on prefix headers, have a look at this entry on Wikipedia. Regarding prefix header best practices, check out this StackOverflow post.
4. A Custom Log Example
Now add an NSLog anywhere in your project code. In my case, I decide to add one within AppDelegate.m’s method -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
.
int result = 20;NSLog(@"Value of result : %d", result);
If you build and run the project with the Debug configuration now, you should see something like this:
([AppDelegate application:didFinishLaunchingWithOptions:]) (AppDelegate.m:21) Value of result : 20
Cheers! This output is much more useful than the default implementation. Hopefully you find that this technique will save you a lot of time while debugging your own programs!
- Customize NSLog for Easier Debugging
- Debugging Tools for Windows
- Debugging Tools for Windows
- Design for debugging
- Allow Debugging for SharePoint
- gcc compiling for debugging
- Debugging Portal for linux
- Process Functions for Debugging
- Thread Functions for Debugging
- Customize My Profile Tabs for SharePoint 2010
- Customize Table View Cells for UITableView
- Debugging Strategies For .NET Developers
- Debugging techniques for PHP programmers
- Configuring Visual Studio for Debugging
- Gadgets for Windows Sidebar Debugging
- Exception Handling Functions for Debugging
- Tips for debugging on Linux
- An easy way to customize a scrollbar for a control
- Object.prototype.toString.call 判断一个对象的类型
- Struts2拦截器的简单示例
- hdu 题目 (最小生成树 prim算法)
- 为开发者准备的15 款Tooltip工具提示jQuery插件
- 如何在oracle中查询所有用户表的表名、主键名称、索引、外键等
- Customize NSLog for Easier Debugging
- HQL: Hibernate查询语言
- 20 个 jQuery 和 CSS 的文本特效插件
- 开启设计模式之旅(一)
- How to Have Two Versions of the Same App on Your Device
- Value must be an existing directory配置tomcat问题?
- TortoiseGit配合msysGit在Git@OSC代码托管的傻瓜教程
- Xcode 5 Finally Makes Interface Builder a Viable Option for Teams
- 26个Jquery使用小技巧