#define iTunesFileSharingEnabled ...我该怎么声明这个

时间:2013-02-04 20:56:51

标签: xcode cocoa

我想根据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则将某些指令定义为true,如果不是则为NO。

我如何声明?

感谢。


编辑:

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

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

#if iTunesFileSharingEnabled
#error TURN OFF FILE SHARING
#endif

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

2 个答案:

答案 0 :(得分: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 Settings中输入Preprocessor Macro

HAS_ITUNES_FILESHARING=1

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

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

这样,您始终可以告诉预处理器宏与配置匹配。如果您只调用一次(在+(void)initialize中,则根本不会产生性能影响。

答案 1 :(得分:0)

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

据推测,你实际上并没有自己的左手和右手在交叉目的上工作时遇到麻烦 - 更可能是你正在编写代码(希望关闭iTunes文件共享)的情况其他人使用过的(可能打开了它)?

在这种情况下,您最好的办法是文件(或许可)。与库的用户通信,它应仅在没有iTunes文件共享的项目中使用。换句话说:如果你把你的源代码提供给另一个程序员,你已经放弃了对他们用它做什么的控制权,但是你仍然可以给出关于如何最好地使用它的建议。 (或让您的律师让他们同意仅以您指定的方式使用您的软件,但这不再是编程问题,而且这不是法律咨询论坛。)

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