在导入之前对框架进行条件编译检查

我正在寻找一种方法来检查一个框架是否存在和/或如果它的类定义,在导入和使用该框架之前。 具体来说,该框架是资产库。

目前,我可以用Core Data框架来做这件事,因为该框架有一个名为CoreDataDefines.h的文件,它提供了一个预处理指令_COREDATADEFINES_H。 这允许我简单地检查这样的定义:

#ifdef _COREDATADEFINES_H #import <CoreData/CoreData.h> // do something with Core Data #else // do something without using Core Data #endif 

不幸的是,Assets Library没有提供明确的定义头文件,所以我正在寻找一种方法来编写我自己的#define语句,在导入之前可以检查框架的存在,就像我为上面的Core Data所做的一样。

我试过这个:

 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000 // import assets library if defined ! #define ASSETSLIBRARY_DEFINE (NSClassFromString(@"ALAsset") != nil) #if ASSETSLIBRARY_DEFINE #import <AssetsLibrary/AssetsLibrary.h> #endif #endif 

…但没有运气。
编译器告诉我“令牌不是预处理器子expression式中的有效二进制运算符”。

任何帮助总是非常感激。

如果你知道什么类应该与框架导入,你可以检查是否加载:

 BOOL isFrameworkLoaded = (NSClassFromString(@"MyClassNameFromTheFramework") != nil); 

你在这里做什么是非常错误的。 _COREDATADEFINES_H定义你在CoreDataDefines.h中看到的是被称为sentinal的值,一种古老的C技术可以避免同一个头文件的多重包含。

你当然不应该在你自己的代码中使用它,并且只能说明这个头文件已经被包含在别的地方了。 如果没有定义,那就意味着头没有被包含,而不是框架本身是不可靠的。

我不确定你正在做什么,但是看起来你想用macros来决定使用框架的代码和不使用框架的代码。 如果你想在编译时做到这一点,唯一的select是定义自己的macros,并用一些编译器选项将它们设置在目标中。 例如,要启用使用资产库的代码,您可以在“其他C标志”构build设置中对其进行定义:

 -DUSE_ASSETS_FRAMEWORK 

然后在你的代码中使用这个:

 #ifdef USE_ASSETS_FRAMEWORK #import <AssetsLibrary/AssetsLibrary.h> // code that uses assets framework #else // code that does not use assets framework #endif 

如果您希望能够在运行时检测应用程序是否与框架链接,并且该框架存在于当前iOS版本中,则应使用Applebuild议的标准方法,即testing任何类别或函数的存在需要:

 if (NSClassFromString(@"ALAsset")) { // ALAsset is available } } else { // ALAsset not available } 

对于这种事情,我有一些窍门……尽pipe接下来的事情可能并不能完全解决你详细描述的问题,但这可能会帮助你find最终的解决scheme……第一个“策略”可以在“脚本构build阶段”中被调用。 这可以用很多方式,但在这个例子中,它testing框架是有效的(根据otool ,然后做一些相应的“后处理”,然后再次testing..等等..

 function test { "$@"; status=$?; if [ $status -ne 0 ]; then echo "error with $1"; fi return $status } PRODUCT_PATH="${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}" BINARY="$PRODUCT_PATH/${PRODUCT_NAME}" MAC="/Library/Frameworks/" SYSTEM_PRODUCT="$MAC/${WRAPPER_NAME}" test otool -l "$BINARY" #/Library/Frameworks/AtoZ.framework/AtoZ if [ $status -ne 0 ]; then sudo rm -r "$SYSTEM_PRODUCT" sudo cp -r "$PRODUCT_PATH" "$SYSTEM_PRODUCT" test otool -l "$BINARY" if [ $status == 0 ]; then cd "${PRODUCT_PATH}" ln -sF Versions/Current/Frameworks Frameworks fi 

下一个在这个智慧免费的手下来是性感的,适当命名的NSBundle方法.. preflightAndReturnError

 NSBundle *b = [NSBundle bundleWithPath:path]; NSError *e = nil; BOOL okdok = [b preflightAndReturnError:&e]; if (okdok) okdok = [b load]; if (!okdok) { [self jumpOffABridge:nil]; goto hell; } 

机会虽然 …你会.. OK DOK ,到时间load完成。

Interesting Posts