我想根据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
如果打开文件共享,我希望编译器失败。
答案 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不会在那里阅读。再次,沟通是你最好的选择。)