Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom NSLog Method ( Variadic )

I am trying to create a custom NSLog() method , DNSLog() , which executes the NSLog only if the debug variable is true.

-(void)DNSLog:(NSString *)formatString, ...
{
    if(debug){
        va_list args;
        va_start(args, formatString);
        NSLog([[NSString alloc] initWithFormat:formatString arguments:args]);
        va_end(args);
    }
}

But when I try calling it using

DNSLog(@"Hello %d",x);

I receive a compilation error :

Undefined symbols for architecture i386:
  "_DZNSLog", referenced from:
      -[RestaurantInfoViewController viewDidLoad] in RestaurantInfoViewController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I have used this as a reference : http://www.cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html

Where am I going wrong ?

like image 238
Kyuubi Avatar asked Jun 06 '13 05:06

Kyuubi


2 Answers

You have confused methods and functions - Objective-C has both. NSLog is a standard function so you call it as NSLog(...). You have defined a method:

-(void)DNSLog:(NSString *)formatString, ...

but tried to call it as a function. To call your method you need to do:

[self DNSLog:@"Hello %d", x];

As your code compiles you must have a global or instance debug variable. If it is a global then you could define DNSLog as a function (this won't work if debug is an instance variable as only methods can directly access those). The function would start:

 void DNSLog(NSString *formatString, ...)

The body of the function will be the same as for the method.

NSLog also has an attribute, NS_FORMAT_FUNCTION, on it to tell the compiler that it takes a format string as an argument, seeing this the compiler will check the format string and arguments to see that they match. To do this for your method or function write:

-(void)DNSLog:(NSString *)formatString, ... NS_FORMAT_FUNCTION(1,2);

or:

void DNSLog(NSString *formatString, ...)  NS_FORMAT_FUNCTION(1,2);

in the interface or header file.

HTH.

like image 123
CRD Avatar answered Sep 24 '22 23:09

CRD


Instead of using a custom method, try adding this macro to your app, perhaps in your .pch file.

#ifdef DEBUG
#define MyLog(x, ...) NSLog(@"%s %d: " x, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define MyLog(x, ...)
#endif

This will run a custom log I call MyLog when in debug mode, and when in release, it wont do anything. It also prints out some other useful information like the file and line number of the log.

like image 27
Eric Avatar answered Sep 24 '22 23:09

Eric