6

我正在尝试创建一个自定义NSLog()方法,DNSLog()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

我哪里错了?

4

3 回答 3

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。

于 2013-06-06T06:19:46.063 回答
13

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

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

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

于 2013-06-06T05:39:51.287 回答
11

谢谢大家对初学者的非常“宝贵”、“鼓励”和“支持”的回答。

我发现了我的错误,这是更正后的工作代码:

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 函数调用来调用它。

于 2013-06-06T06:12:14.670 回答