Redirecting macro definition in Objective-C (Xcode) - objective-c

I am currently using the "Flexible Logging" as shown here, for example:
LogInfo(#"Do you object to this %# date object?", [NSDate new]);
LogDebug(#"I'll take this out if ever I solve this bug");
LogError(#"Don't do that: %#", [NSException exceptionWithName: #"CRYING" reason: #"Spilled milk" userInfo:nil]);
I have now added the Crashlytics library to my project and this to the Prefix.pch:
#ifdef DEBUG
#define CLS_LOG(__FORMAT__, ...) CLSNSLog((#"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define CLS_LOG(__FORMAT__, ...) CLSLog((#"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
Is there a way to redirect all log messages from LogInfo, LogDebug, LogError, etc. to CLS_LOG?
I did this for TestFlight:
#define NSLog TFLog
But doing the same for Crashlytics does not work, and gives warnings about redefining macros:
#define LogDebug CLS_LOG

Related

NSLog is throwing error while trying to disable it in the project

I want to disable all the NSLog in my project. In the project I have added one library. When I tried to disable all the NSLog in the project other than the library it is working fine.
But when I try to add it in the library project it is throwing error.
I tried this code
// Enable debug (NSLog)
//#define DEVLOPENV 1 // comment this to disable the nslogs
#ifdef DEVLOPENV
# define NSLog(fmt, ...) NSLog((#"\n%s : [Line - %d] \n" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define NSLog(fmt, ...)
#endif
The xcode is throwing
Can anyone please help me how to fix this error.
When the macro is expanded at compile time, your code will look like this:
dict1 ? [temp addObject:dict1] : ;
Not providing a "else" value for the ternary operator is not possible, hence the error.
You could define your macro like so to work around the problem:
#ifdef DEVLOPENV
# define NSLog(fmt, ...) NSLog((#"\n%s : [Line - %d] \n" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define NSLog(fmt, ...) (void)(0)
#endif
Your code will then look like:
dict1 ? [temp addObject:dict1] : (void)(0);
(void)(0) is a no-op, achieving the expected behavior.
However, in this particular case, I'd recommend avoiding using a ternary operator. A classic if...else construct would be more readable and appropriate.
You should remove ";" at the end of the define.
#define NSLog(fmt, ...) NSLog((#"\n%s : [Line - %d] \n" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)

NSLog macro to print out if it is on the main thread

My current DEB_LOG macro extends NSLog to also print out the object, method, and line where it is being logged:
#define DEB_LOG(__FORMAT__,...) NSLog((#"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
I would also like to expand it to report if it is on the main thread, if possible.
[NSThread isMainThread]
Is that possible?
This should do it:
#define DEB_LOG(__FORMAT__,...) NSLog((#"%s line %d%s $ " __FORMAT__), \
__PRETTY_FUNCTION__, __LINE__, \
([NSThread isMainThread] ? " (main thread)" : ""), \
##__VA_ARGS__)
The output generated from
DEB_LOG(#"%#", #"Hello world");
is
-[AppDelegate application:didFinishLaunchingWithOptions:] line 20 (main thread) $ Hello world
Sure you can!
Could look something like this:
#define NSLog(__FORMAT__, ...) NSLog((#"%s line %d [Thread:%s] " __FORMAT__), \
__PRETTY_FUNCTION__, __LINE__, ([NSThread isMainThread] ? "Main" : "Background"), \
##__VA_ARGS__)

Wrap calls to NSLog in Objective-C [duplicate]

This question already has answers here:
Setting a flag in compiler for NSLog not to show
(7 answers)
Closed 9 years ago.
I want to be able to wrap all calls to NSLog in my Class so I can have a single place to enable/disable logging.
I can't figure out how to accept variable numbers of arguments to my method and then hand them on to NSLog.
Examples, please.
for a logger I'd just go with a macro
#if DEBUG
#warning LOGGING ENABLED
#define DebugLog(fmt, ...) NSLog((#"%s " fmt), __PRETTY_FUNCTION__, ##__VA_ARGS__)
#else
#define DebugLog(...)
#endif
BUT
if you want to work with variable arguments:
declare your method as so it takes a variable number of arguments
+ (id)stringWithFormat:(NSString *)format, ...;
use the va_* C functions to interact with the variable arguments
va_start - Initializes a va_list
va_arg - Fetches the next argument out of the list.
va_end - Releases any memory by the list of vas
DEMO for the logging
#import <Foundation/Foundation.h>
#define DEBUG 1
#if DEBUG
#warning LOGGING ENABLED
#define DebugLog(fmt, ...) NSLog((#"%s " fmt), __PRETTY_FUNCTION__, ##__VA_ARGS__)
#else
#define DebugLog(...)
#endif
int main(int argc, char *argv[]) {
#autoreleasepool {
id v = #1;
DebugLog(#"bla: %#", v);
}
}
I use a handy set of Macros from Marcus Zarra:
#ifdef DEBUG
#define DLog(...) NSLog(#"%s %#", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#define ALog(...) [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__ encoding:NSUTF8StringEncoding] file:[NSString stringWithCString:__FILE__ encoding:NSUTF8StringEncoding] lineNumber:__LINE__ description:__VA_ARGS__]
#else
#define DLog(...) do { } while (0)
#ifndef NS_BLOCK_ASSERTIONS
#define NS_BLOCK_ASSERTIONS
#endif
#define ALog(...) NSLog(#"%s %#", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#endif
#define ZAssert(condition, ...) do { if (!(condition)) { ALog(__VA_ARGS__); }} while(0)
This doesn't need any configuration as DEBUG and RELEASE are defined by Xcode as standard. This provides:
DLog() Only emits an NSLog in DEBUG
ALog() Throws an assertion with the message in DEBUG, and emits an NSLog in RELEASE
ZAssert() Throws an Assertion if the condition fails in DEBUG, and emits an NSLog if the condition fails in RELEASE.
And the logs are pretty printed - showing the class and method where the log is emitted.

Objective-C macro to return a string with the function and the line number while accepting a string with a variable number of arguments?

I've found a bunch of macro variations on how to use NSLog as a basis and adding PRETTY_FUNC and LINE but all the variations of those macros simply output the result to the console.
I'd like to have a macro that can take a format with a variable number of arguments, add the name of the method and line number where it was called and then return an NSString but so far, the compiler always complains where I call it. My latest version is as follow:
#define FileLog(format, ...) {\
return [NSString stringWithFormat:#"\n %s [Line %d] \n %#",
__PRETTY_FUNCTION__,
__LINE__,
[NSString stringWithFormat:(format), ##__VA_ARGS__]];\
}
Each time I call it from my code, the compiler generates one of those errors:
error: expected expression before '{' token
I don't want to write a log class or use a framework for that. There must be a way to do that with a macro? Anyone?
Thanks in advance!
This is entirely possible with a macro, I think you just need a little more background on them.
First, macros are not functions, so the braces are unnecessary (and, in fact, are the cause of your error). A macro is really a fairly dumb "copy/paste" that is automated by the preprocessor, using syntax that it understands.
In order to define a macro that spans multiple lines and creates an NSString "in place", you have to escape the newlines with backslashes, like so:
#define FileLog(format, ...) \
[NSString stringWithFormat:#"\n %s [Line %d] \n %#", \
__PRETTY_FUNCTION__, \
__LINE__, \
[NSString stringWithFormat:format, ##__VA_ARGS__]]
Macros do not "return" like a function does, because, as I mentioned, they are merely a way to "copy/paste" text.
You can use it like so:
int num = 42;
NSLog(#"%#", FileLog(#"some number: %d", num));
If you were to look at the preprocessor output (the file that the preprocessor creates before compilation), the above example would expand to something like:
NSLog(#"%#", [NSString stringWithFormat:#"\n %s [Line %d] \n %#", __PRETTY_FUNCTION__, __LINE__, [NSString stringWithFormat:#"some number: %d", num]]);
Try this....
Create an include file
#define LOG_NOLOG_LEVEL 0
#define LOG_ERROR_LEVEL 1
#define LOG_WARN_LEVEL 2
#define LOG_INFO_LEVEL 3
#define LOG_DEBUG_LEVEL 4
#if LOG_HELPER_LEVEL >= LOG_DEBUG_LEVEL
#define LOGDEBUG(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
#define LOGDEBUG(...)
#endif
#if LOG_HELPER_LEVEL >= LOG_INFO_LEVEL
#define LOGINFO(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
#define LOGINFO(...)
#endif
#if LOG_HELPER_LEVEL >= LOG_WARN_LEVEL
#define LOGWARN(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
#define LOGWARN(...)
#endif
#if LOG_HELPER_LEVEL >= LOG_ERROR_LEVEL
#define LOGERROR(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
#define LOGERROR(...)
#endif
Then create a simple class LogHelper with a single class method as follows....
+ (void) log:(NSString *)message
{
fputs([message cStringUsingEncoding:NSUTF8StringEncoding], stderr);
}
Then in your code, you can put calls like...
LOGDEBUG(#"%s - %d Redirect response received\n%#",__FILE__,
__LINE__,[redirectRequest dumpInfo]);
You can set the LOG_HELPER_LEVEL to the level of logging you want to produce. If you set the level at say LOG_WARN_LEVEL, then no code will be included in your app for INFO or DEBUG levels, so it's easy to package your app up for release.
Hope this helps...
From Viraj Thenuwara, who was my iOS Senior developer who trained me :-)
This macro is much more simpler in its definition and also its usage, than the things mentioned above.
#define debug 1
#if debug
#define AppLog(fmt, ...) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define AppLog(...)
#endif
And it's usage is as follows:
NSString *url = #"http://google.com";
AppLog(#"url %# and id %d", url, 5);
This AppLog line will print out it's given content only if the debug constant is equal to 1. At the Production time or in anytime you don't want to print the log lines you can disable it by turning that 1 into 0.
And it's console out put will be seen as follows:
Hope this will be helpful to someone else!
Cheers!

How to print out the method name and line number and conditionally disable NSLog?

I'm doing a presentation on debugging in Xcode and would like to get more information on using NSLog efficiently.
In particular, I have two questions:
is there a way to easily NSLog the current method's name / line number?
is there a way to "disable" all NSLogs easily before compiling for release code?
Here are some useful macros around NSLog I use a lot:
#ifdef DEBUG
# define DLog(fmt, ...) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
# define DLog(...)
#endif
// ALog always displays output regardless of the DEBUG setting
#define ALog(fmt, ...) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
The DLog macro is used to only output when the DEBUG variable is set (-DDEBUG in the projects's C flags for the debug confirguration).
ALog will always output text (like the regular NSLog).
The output (e.g. ALog(#"Hello world") ) will look like this:
-[LibraryController awakeFromNib] [Line 364] Hello world
I've taken DLog and ALog from above, and added ULog which raises a UIAlertView message.
To summarize:
DLog will output like NSLog only when the DEBUG variable is set
ALog will always output like NSLog
ULog will show the UIAlertView only when the DEBUG variable is set
#ifdef DEBUG
# define DLog(fmt, ...) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define DLog(...)
#endif
#define ALog(fmt, ...) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#ifdef DEBUG
# define ULog(fmt, ...) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"%s\n [Line %d] ", __PRETTY_FUNCTION__, __LINE__] message:[NSString stringWithFormat:fmt, ##__VA_ARGS__] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil]; [alert show]; }
#else
# define ULog(...)
#endif
This is what it looks like:
+1 Diederik
NSLog(#"%s %d %s %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);
Outputs file name, line number, and function name:
/proj/cocoa/cdcli/cdcli.m 121 managedObjectContext managedObjectContext
__FUNCTION__ in C++ shows mangled name __PRETTY_FUNCTION__ shows nice function name, in cocoa they look the same.
I'm not sure what is the proper way of disabling NSLog, I did:
#define NSLog
And no logging output showed up, however I don't know if this has any side effects.
Here one big collection of debug constants that we use. Enjoy.
// Uncomment the defitions to show additional info.
// #define DEBUG
// #define DEBUGWHERE_SHOWFULLINFO
// #define DEBUG_SHOWLINES
// #define DEBUG_SHOWFULLPATH
// #define DEBUG_SHOWSEPARATORS
// #define DEBUG_SHOWFULLINFO
// Definition of DEBUG functions. Only work if DEBUG is defined.
#ifdef DEBUG
#define debug_separator() NSLog( #"────────────────────────────────────────────────────────────────────────────" );
#ifdef DEBUG_SHOWSEPARATORS
#define debug_showSeparators() debug_separator();
#else
#define debug_showSeparators()
#endif
/// /// /// ////// /////
#ifdef DEBUG_SHOWFULLPATH
#define debug_whereFull() debug_showSeparators(); NSLog(#"Line:%d : %s : %s", __LINE__,__FILE__,__FUNCTION__); debug_showSeparators();
#else
#define debug_whereFull() debug_showSeparators(); NSLog(#"Line:%d : %s : %s", __LINE__,[ [ [ [NSString alloc] initWithBytes:__FILE__ length:strlen(__FILE__) encoding:NSUTF8StringEncoding] lastPathComponent] UTF8String ] ,__FUNCTION__); debug_showSeparators();
#endif
/// /// /// ////// /////
#define debugExt(args,...) debug_separator(); debug_whereFull(); NSLog( args, ##__VA_ARGS__); debug_separator();
/// /// /// ////// ///// Debug Print Macros
#ifdef DEBUG_SHOWFULLINFO
#define debug(args,...) debugExt(args, ##__VA_ARGS__);
#else
#ifdef DEBUG_SHOWLINES
#define debug(args,...) debug_showSeparators(); NSLog([ NSString stringWithFormat:#"Line:%d : %#", __LINE__, args ], ##__VA_ARGS__); debug_showSeparators();
#else
#define debug(args,...) debug_showSeparators(); NSLog(args, ##__VA_ARGS__); debug_showSeparators();
#endif
#endif
/// /// /// ////// ///// Debug Specific Types
#define debug_object( arg ) debug( #"Object: %#", arg );
#define debug_int( arg ) debug( #"integer: %i", arg );
#define debug_float( arg ) debug( #"float: %f", arg );
#define debug_rect( arg ) debug( #"CGRect ( %f, %f, %f, %f)", arg.origin.x, arg.origin.y, arg.size.width, arg.size.height );
#define debug_point( arg ) debug( #"CGPoint ( %f, %f )", arg.x, arg.y );
#define debug_bool( arg ) debug( #"Boolean: %#", ( arg == YES ? #"YES" : #"NO" ) );
/// /// /// ////// ///// Debug Where Macros
#ifdef DEBUGWHERE_SHOWFULLINFO
#define debug_where() debug_whereFull();
#else
#define debug_where() debug(#"%s",__FUNCTION__);
#endif
#define debug_where_separators() debug_separator(); debug_where(); debug_separator();
/// /// /// ////// /////
#else
#define debug(args,...)
#define debug_separator()
#define debug_where()
#define debug_where_separators()
#define debug_whereFull()
#define debugExt(args,...)
#define debug_object( arg )
#define debug_int( arg )
#define debug_rect( arg )
#define debug_bool( arg )
#define debug_point( arg )
#define debug_float( arg )
#endif
There are a new trick that no answer give. You can use printf instead NSLog. This will give you a clean log:
With NSLog you get things like this:
2011-11-03 13:43:55.632 myApp[3739:207] Hello Word
But with printf you get only:
Hello World
Use this code
#ifdef DEBUG
#define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
#define NSLog(...) {}
#endif
My answer to this question might help, looks like it's similar to the one Diederik cooked up. You may also want to replace the call to NSLog() with a static instance of your own custom logging class, that way you can add a priority flag for debug/warning/error messages, send messages to a file or database as well as the console, or pretty much whatever else you can think of.
#define DEBUG_MODE
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( #"<%p %#:(%d)> %#", self,
[[NSString stringWithUTF8String:__FILE__] lastPathComponent],
__LINE__,
[NSString stringWithFormat:(s),
##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif
Disabling all NSLogs, for somebody allergic to MACROS, here is something that you can compile too:
void SJLog(NSString *format,...)
{
if(LOG)
{
va_list args;
va_start(args,format);
NSLogv(format, args);
va_end(args);
}
}
And, use it almost like NSLog:
SJLog(#"bye bye NSLogs !");
From this blog: https://whackylabs.com/logging/ios/2011/01/19/ios-moving-in-and-out-of-nslogs/
To complement the answers above, it can be quite useful to use a replacement for NSLog in certain situations, especially when debugging. For example, getting rid of all the date and process name/id information on each line can make output more readable and faster to boot.
The following link provides quite a bit of useful ammo for making simple logging much nicer.
http://cocoaheads.byu.edu/wiki/a-different-nslog
It's easy to change your existing NSLogs to display line number and class from which they are called. Add one line of code to your prefix file:
#define NSLog(__FORMAT__, ...) NSLog((#"%s [Line %d] " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
It is simple,for Example
-(void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
Output:
-[AppDelegate applicationWillEnterForeground:]
building on top of above answers, here is what I plagiarized and came up with. Also added memory logging.
#import <mach/mach.h>
#ifdef DEBUG
# define DebugLog(fmt, ...) NSLog((#"%s(%d) " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define DebugLog(...)
#endif
#define AlwaysLog(fmt, ...) NSLog((#"%s(%d) " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#ifdef DEBUG
# define AlertLog(fmt, ...) { \
UIAlertView *alert = [[UIAlertView alloc] \
initWithTitle : [NSString stringWithFormat:#"%s(Line: %d) ", __PRETTY_FUNCTION__, __LINE__]\
message : [NSString stringWithFormat : fmt, ##__VA_ARGS__]\
delegate : nil\
cancelButtonTitle : #"Ok"\
otherButtonTitles : nil];\
[alert show];\
}
#else
# define AlertLog(...)
#endif
#ifdef DEBUG
# define DPFLog NSLog(#"%s(%d)", __PRETTY_FUNCTION__, __LINE__);//Debug Pretty Function Log
#else
# define DPFLog
#endif
#ifdef DEBUG
# define MemoryLog {\
struct task_basic_info info;\
mach_msg_type_number_t size = sizeof(info);\
kern_return_t e = task_info(mach_task_self(),\
TASK_BASIC_INFO,\
(task_info_t)&info,\
&size);\
if(KERN_SUCCESS == e) {\
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; \
[formatter setNumberStyle:NSNumberFormatterDecimalStyle]; \
DebugLog(#"%# bytes", [formatter stringFromNumber:[NSNumber numberWithInteger:info.resident_size]]);\
} else {\
DebugLog(#"Error with task_info(): %s", mach_error_string(e));\
}\
}
#else
# define MemoryLog
#endif
New addition to DLog. Instead of totally removing debug from released application, only disable it. When user has problems, which would require debugging, just tell how to enable debug in released application and request log data via email.
Short version: create global variable (yes, lazy and simple solution) and modify DLog like this:
BOOL myDebugEnabled = FALSE;
#define DLog(fmt, ...) if (myDebugEnabled) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
Longer answer at Jomnius iLessons iLearned: How to Do Dynamic Debug Logging in Released Application
For some time I've been using a site of macros adopted from several above. Mine focus on logging in the Console, with the emphasis on controlled & filtered verbosity; if you don't mind a lot of log lines but want to easily switch batches of them on & off, then you might find this useful.
First, I optionally replace NSLog with printf as described by #Rodrigo above
#define NSLOG_DROPCHAFF//comment out to get usual date/time ,etc:2011-11-03 13:43:55.632 myApp[3739:207] Hello Word
#ifdef NSLOG_DROPCHAFF
#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#endif
Next, I switch logging on or off.
#ifdef DEBUG
#define LOG_CATEGORY_DETAIL// comment out to turn all conditional logging off while keeping other DEBUG features
#endif
In the main block, define various categories corresponding to modules in your app. Also define a logging level above which logging calls won't be called. Then define various flavours of NSLog output
#ifdef LOG_CATEGORY_DETAIL
//define the categories using bitwise leftshift operators
#define kLogGCD (1<<0)
#define kLogCoreCreate (1<<1)
#define kLogModel (1<<2)
#define kLogVC (1<<3)
#define kLogFile (1<<4)
//etc
//add the categories that should be logged...
#define kLOGIFcategory kLogModel+kLogVC+kLogCoreCreate
//...and the maximum detailLevel to report (use -1 to override the category switch)
#define kLOGIFdetailLTEQ 4
// output looks like this:"-[AppDelegate myMethod] log string..."
# define myLog(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((#"%s " format), __PRETTY_FUNCTION__, ##__VA_ARGS__);}
// output also shows line number:"-[AppDelegate myMethod][l17] log string..."
# define myLogLine(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((#"%s[l%i] " format), __PRETTY_FUNCTION__,__LINE__ ,##__VA_ARGS__);}
// output very simple:" log string..."
# define myLogSimple(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((#"" format), ##__VA_ARGS__);}
//as myLog but only shows method name: "myMethod: log string..."
// (Doesn't work in C-functions)
# define myLog_cmd(category,detailLevel,format,...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((#"%#: " format), NSStringFromSelector(_cmd), ##__VA_ARGS__);}
//as myLogLine but only shows method name: "myMethod>l17: log string..."
# define myLog_cmdLine(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((#"%#>l%i: " format), NSStringFromSelector(_cmd),__LINE__ , ##__VA_ARGS__);}
//or define your own...
// # define myLogEAGLcontext(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((#"%s>l%i (ctx:%#)" format), __PRETTY_FUNCTION__,__LINE__ ,[EAGLContext currentContext], ##__VA_ARGS__);}
#else
# define myLog_cmd(...)
# define myLog_cmdLine(...)
# define myLog(...)
# define myLogLine(...)
# define myLogSimple(...)
//# define myLogEAGLcontext(...)
#endif
Thus, with current settings for kLOGIFcategory and kLOGIFdetailLTEQ, a call like
myLogLine(kLogVC, 2, #"%#",self);
will print but this won't
myLogLine(kLogGCD, 2, #"%#",self);//GCD not being printed
nor will
myLogLine(kLogGCD, 12, #"%#",self);//level too high
If you want to override the settings for an individual log call, use a negative level:
myLogLine(kLogGCD, -2, #"%#",self);//now printed even tho' GCD category not active.
I find the few extra characters of typing each line are worth as I can then
Switch an entire category of comment on or off (e.g. only report those calls marked Model)
report on fine detail with higher level numbers or just the most important calls marked with lower numbers
I'm sure many will find this a bit of an overkill, but just in case someone finds it suits their purposes..