导入前框架的条件编译检查

时间:2011-09-07 09:46:09

标签: objective-c c ios conditional


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

目前,我可以使用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

不幸的是,资产库没有提供明确的定义头文件,所以我正在寻找一种方法来编写我自己的#define语句,可以在导入之前检查框架的存在,就像我有完成上面的核心数据。

我试过这个:

#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

......但没有运气。
编译器告诉我“Token不是预处理器子表达式中的有效二元运算符。”

任何帮助总是非常感谢。

3 个答案:

答案 0 :(得分:4)

如果您知道应该使用框架导入哪个类,您可以检查它是否已加载:

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

答案 1 :(得分:1)

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

您当然不应该在自己的代码中使用它,并且sentinal的存在只会告诉您标题已经包含在其他地方。如果没有定义sentinal,它只是意味着标题包含 not ,而不是框架本身是不存在的。

我不确定您要做什么,但看起来您希望使用宏来决定使用框架的代码和不使用框架的代码。如果您想在编译时执行此操作,您唯一的选择是定义自己的宏并使用一些编译器选项在目标中设置它们。例如,要启用使用资产库的代码,您可以在“其他C标志”构建设置中定义此代码:

-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版本上,则应使用Apple建议的标准方法来测试任何类的存在或你需要的功能:

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

答案 2 :(得分:1)

我有一些这方面的技巧......虽然接下来可能没有完全解决你详细解决的问题,但这可能有助于找到你的终极解决方案......第一个“策略”可以在“脚本构建”中调用相”。这可以在很多方面使用,但是在这个例子中它测试框架是有效的(根据otool,然后相应地进行一些“后处理”...然后再次测试..等等上..

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

这个智慧 free-for-all 的下一个让我失望的是性感的,恰如其分的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