2013-06-06 18 views
6

我想创建一个自定义NSLog()方法,DNSLog(),只有在调试变量为true时才执行NSLog自定义NSLog方法(变量)

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

但是当我尝试使用

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

调用它,我收到一个编译错误:

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) 

我已经使用这个作为参考:http://www.cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html

我在哪里出错了?

+5

我想你应该在学习C之前尝试进入先进的东西。看起来你甚至不能区分C函数的语法和Objective-C方法...... – 2013-06-06 05:19:10

+1

此外,你的代码容易受格式字符串攻击/错误的影响。你应该使用'NSLogv(formatString,args);'来代替。 – 2013-06-06 05:20:54

回答

14

您有困惑方法函数 - Objective-C同时具有。 NSLog是标准功能,因此您可以将其称为NSLog(...)。您已经定义了一种方法:

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

但试图将其称为函数。打电话给你的方法,你需要做的:

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

当你的代码编译必须有一个全球性或实例debug变量。如果它是一个全球那么你可以将DNSLog定义为一个函数(如果debug是一个实例变量,只有方法可以直接访问它们,这将不起作用)。该功能将开始:

void DNSLog(NSString *formatString, ...) 

该函数的主体将与该方法相同。

NSLog也有一个属性NS_FORMAT_FUNCTION,它告诉编译器它将一个格式字符串作为参数,看到这一点,编译器将检查格式字符串和参数以查看它们是否匹配。在接口或头文件

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

:要为您的方法或函数写这样做:

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

或。

HTH。

+0

谢谢...是的,我意识到这个错误。现在所有的工作:) – Kyuubi

+1

@Kyuubi - 是的,当我不在的时候输入这个,你可以自己想出一些,不过不要忘了'NS_FORMAT_FUNCTION' - 它有助于许多。 – CRD

+0

明白了。附加到我的功能相同。 – Kyuubi

12

而不是使用自定义方法,请尝试将此宏添加到您的应用程序,也许在您的.pch文件中。

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

这将运行一个自定义日志,我调用MyLog时,在调试模式,并在发布时,它不会做任何事情。它还打印出一些其他有用的信息,例如日志的文件和行号。

+1

其实他的问题是关于只在“调试变量为真”时进行日志记录。他的代码似乎表明他有一个他正在控制的独立调试变量。此外,H2CO3只是以他看到的方式调用它。我有同样的感觉。我很少在自己的答案中提供代码,因为我知道如果我做的人只会复制和粘贴它,然后当它不能完全按照书面的原则工作时就会不知所措。我觉得人们应该明白他们写的代码。 – borrrden

+0

那么是不是解决方案发布答案​​,以帮助通知他,让他可以理解?也许我们创建一个实际上有助于学习和实施这种方法的文章。再补充一点,分享不同的做事方式不应该是错的,但我现在明白你的观点。 – Eric

+0

谢谢。这也适用! 但是在将来我可能在日志函数中有一个复杂的布尔表达式和一个嵌套的if-else,所以试图一起实现一个新函数,而不是一个MACRO。 – Kyuubi

9

感谢大家为你的初学者提供的“极具价值”,“鼓舞”和“支持”答案。

我发现我的错误,这里是修正后加工代码:

void ZNSLog(NSString *format, ...){ 
    if(!ENABLE_DEBUGGING) 
     return; 
    va_list args; 
    va_start(args, format); 
    NSLogv(format, args); 
    va_end(args); 
} 

ZNSLog(@"Hello"); 

我用以前的方法是一个Objective C的方法

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

我试图使用C调用函数调用。