我是Objective-C的新手
我尝试整合asl_log
。出于某种原因,静态bool在其他文件中始终具有NO
值。
我创建了标题MyLogger.h
,内容为:
#import <Foundation/Foundation.h>
#import <asl.h>
static bool gLoggingEnabled = NO;
#define __AF_MAKE_LOG_FUNCTION(LEVEL, NAME) \
static inline void NAME(NSString *format, ...)\
{ \
if (!gLoggingEnabled) return; \
va_list arg_list; \
va_start(arg_list, format); \
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list]; \
asl_add_log_file(NULL, STDERR_FILENO); \
asl_log(NULL, NULL, (LEVEL), "Prog_ASL: %s", [formattedString UTF8String]); \
va_end(arg_list); \
}
__AF_MAKE_LOG_FUNCTION(ASL_LEVEL_DEBUG, AFLogDebug)
#undef __AF_MAKE_LOG_FUNCTION
您可以看到我使用static bool gLoggingEnabled
作为切换。
从我的主项目文件中我做到了:
#import "AFLogger.h"
// ...
gLoggingEnabled = YES;
if (gLoggingEnabled) {
asl_add_log_file(NULL, STDERR_FILENO);
//set log level
asl_set_filter(NULL, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
} else {
asl_remove_log_file(NULL, STDERR_FILENO);
}
AFLogDebug(@"flag is %@", gLoggingEnabled ? @"Yes" : @"No");
// -> flag is Yes
但是它仅适用于一个文件。
我还有其他.m
文件:
#import "AFLogger.h"
//...
NSLog(@"flag is %@", gLoggingEnabled ? @"Yes" : @"No");
// -> flag is No
// AFLogDebug prints nothing
为什么static bool gLoggingEnabled
在其他文件中的值为No
如何解决?
[编辑]
我想避免使用extern
答案 0 :(得分:2)
它是static
所以您导入MyLogger.h
的每个.m文件都会获得自己的gLoggingEnabled
变量副本。
如果您想要一个应用程序范围内的变量,那么您需要更改两件事。
在MyLogger.h
中,您需要将static
更改为extern
:
extern bool gLoggingEnabled;
在MyLogger.m
中,您需要添加:
bool gLoggingEnabled = NO;
该声明与extern
配对。这是应用程序范围的全局变量。
然后在任何文件中,您都可以更改其值:
gLoggingEnabled = YES; // or NO as needed
最后一行将更改整个应用的值(包含MyLogger.h
的任何文件)。
答案 1 :(得分:1)
你所拥有的是变量的定义。你想要的是宣言。不仅如此,static
修饰符限制了它对其定义的编译单元的可见性。实质上,每个.c
或.m
文件都有自己的gLoggingEnabled
副本,仅限.c
它可以看到。
您需要做的是在一个.m
或bool gLoggingEnabled = false; // Note, using C11 bool definitions
文件中创建一个非静态文件范围变量
extern bool gLoggingEnabled;
然后在标题中添加外部声明。这就像对编译器的承诺,您可能没有为当前编译单元中的变量定义存储,但它将在链接时完成。
- (Item *)copy
{
Item *duplicateInstance = [[Item alloc] init];
duplicateInstance.XXXX = self.XXXX;
// Copy all your member values to the new instance
return duplicateInstance;
}