标题中定义的静态bool仅适用于一个文件,为什么?

时间:2017-03-23 13:51:33

标签: ios objective-c

我是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

2 个答案:

答案 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它可以看到。

您需要做的是在一个.mbool 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;
}