0

我想根据 Info.plist 文件上的 iTunes 文件共享布尔状态的状态创建一个定义。所以,我创建了这个:

#define itunesFileSharingEnabled [[[NSBundle mainBundle] \
objectForInfoDictionaryKey:@"UIFileSharingEnabled"] boolValue]

#if itunesFileSharingEnabled
#define something
#endif

但是 if在预处理器表达式开始时失败并出现错误无效标记

如果我用#define itunesFileSharingEnabled 替换

#define itunesFileSharingEnabled YES

比 if 完美编译。所以错误在前一行。Xcode 不喜欢 #define 行。

如果 iTunes 文件共享是 YES,我想要定义一些指令为真,如果不是,则定义为 NO。

我该如何声明?

谢谢。


编辑:

问题是我不能使用常规 if 在运行时检查 iTunes 文件共享,因为我想使用 #error 或 #warning 指令使编译器失败...

例如,稍后在我的代码中我想使用它

#if iTunesFileSharingEnabled
#error TURN OFF FILE SHARING
#endif

如果打开文件共享,我希望编译器失败。

4

2 回答 2

2

预处理器指令在编译时进行评估。

在预处理器第一次运行之后

#define itunesFileSharingEnabled [[[NSBundle mainBundle] \
objectForInfoDictionaryKey:@"UIFileSharingEnabled"] boolValue]

#if itunesFileSharingEnabled
#define something
#endif

变成

#if [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIFileSharingEnabled"] boolValue]
#define something
#endif

在第二次运行期间,预处理尝试验证[[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIFileSharingEnabled"] boolValue]. 这不起作用,因为这无法在编译时进行评估。这是一个只能在运行时评估的语句。


我不知道你想做的事情是否有可能。(我对预处理器了解不多)。

我想你已经知道你可以在运行时进行这些检查

if ([[[NSBundle mainBundle] \
objectForInfoDictionaryKey:@"UIFileSharingEnabled"] boolValue]) {
    [self foo];
} 
else {
    [self bar];
}

另一种选择是强制执行手动输入的预编译器宏

这会进入您的代码,在某个地方它只被调用一次。可能在您的库的 init 中:

#if HAS_ITUNES_FILESHARING
    if (![[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIFileSharingEnabled"] boolValue]) {
        [NSException raise:@"MBFileSharingNotActiveButDeclaredException" format:@"File sharing is not active but \"HAS_ITUNES_FILESHARING\" is set to 1"];
    }
#else
    if ([[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIFileSharingEnabled"] boolValue]) {
        [NSException raise:@"MBFileSharingActiveButNotDeclaredException" format:@"File sharing is active but you did not declare it as preprocessor macro. Please set \"HAS_ITUNES_FILESHARING\" to 1"];
    }
#endif

这必须在Build Settingsas中输入Preprocessor Macro

HAS_ITUNES_FILESHARING=1

如果HAS_ITUNES_FILESHARING=1未在预处理器宏部分中声明,但文件共享处于活动状态,则代码将引发异常。

如果HAS_ITUNES_FILESHARING=1已声明,但文件共享未激活,代码也会引发异常。

这样,您始终可以判断预处理器宏与配置匹配。如果您只调用一次(+(void)initialize应该完全没有性能影响。

于 2013-02-04T21:08:56.497 回答
0

尽管您只能在运行时(在代码中)检查它,但 iTunes 文件共享是应用程序开发人员在开发中设置的东西。如果您不想共享文件,请不要打开它。

不过,大概你自己的左右手在交叉用途上工作实际上并没有遇到问题——更有可能的是,你正在编写代码(希望关闭 iTunes 文件共享)以供某人使用其他(谁可能打开它)?

在这种情况下,您最好的办法是文档(或许可)。与您的资料库的用户沟通,它应该只在没有 iTunes 文件共享的项目中使用。换句话说:如果您将源代码提供给其他程序员,您已经放弃了对他们如何使用它的控制权,但您仍然可以就如何最好地使用它向他们提供建议。(或者让您的律师让他们同意仅以您指定的方式使用您的软件,但这不再是编程问题,也不是法律咨询论坛。)

(除此之外:您还可以考虑使用构建系统做一些有趣的事情:例如读取项目的主要 Info.plist 的 shell 脚本构建阶段。但是,如果您的库是应用程序的依赖项,则需要先构建它,这意味着 plist 不会在那里供它阅读。同样,沟通是你最好的选择。)

于 2013-02-04T22:19:52.413 回答