我有一个项目,它有一个库子项目,可以导入。我可以访问主项目和子项目的源代码。
子项目使用核心文本。由于子项目必须在 3.2 前后的应用程序上使用,Core Text 是弱链接的,所有与 Core Text 相关的代码都包含在逻辑中:
#if defined(__CORETEXT__) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
这行代码的想法是,如果CoreText没有链接进去,代码就跳过了。如果 iPhone 版本低于 3.2; CoreText 未链接。
这个目标的原因是主要项目(并且有几个)并不都使用Core Text,如果不使用则没有'defined(CoreTEXT)' ,它们不会编译。
这似乎工作正常,并且在使用 Core Text 的项目上一切编译都没有错误。但是在执行时,找不到代码,并且运行时错误类似于“NSString 不响应 XXXX”(部分代码是 NSString 上的一个类别)。
有人遇到过这种情况吗?我的问题(由于是客户工作而部分含糊不清)是否清楚?
理想情况下,我想这样设置,以便在主项目使用 Core Text 时不需要更改子项目。
请注意,__CORETEXT__ 是在 Core Text 框架的 header 中定义的。
更新问题
我已经尝试了迄今为止提供的建议,但它们都无效。也许更多的代码将有助于概述问题。我有一个带有以下标题的类别:
@interface NSString (Internal)
- (NSString *)stringByUnescapingEntities;
- (NSString *)flattenHTML;
- (NSString *)flattenHTMLAndParseParagraphBreaksBOOL)parseBreaks;
- (NSString *)stringByEscapingForURL;
- (NSString *)stringByEscapingForJSON;
#if defined(__CORETEXT__) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
- (CFAttributedStringRef)attributedStringFromHTML;
- (CFAttributedStringRef)attributedStringFromHTMLWithBaseAttributesNSDictionary*)baseAttributes;
#endif
@end
阳性测试
#if block 之外的所有方法都可以完美运行。 #if compile 中的所有方法都完美无缺,没有警告。
阴性测试
如果我将 __CORETEXT__ 更改为类似 __THIS_IS_NOT_REAL__ 的内容,我将收到 block 内方法的编译错误。因此,至少在编译时,我知道 __CORETEXT__ 标志已定义且功能齐全。
运行时问题
但是,当我访问在 #if block 内声明的方法之一时,我在运行时收到以下错误:
-[NSCFString attributedStringFromHTMLWithBaseAttributes:]: unrecognized selector sent to instance 0x689c000
实例 0x689c000 是一个 NSString 。
如果我删除 __CORETEXT__ 逻辑检查,那么只要主项目使用 Core Text,一切都会正常工作。如果主项目未使用 Core Text,则会出现有关缺少链接器的编译错误。
希望能澄清问题。
注意:所有项目都使用 -all_load 标志;因为 TouchXML 已经需要它了。
我创建了一个演示该问题的测试项目。
Test Project
Best Answer-推荐答案 strong>
您指出至少有一个最终丢失的东西是 NSString 的类别方法这一事实使我认为您遇到了一个可爱的问题,这似乎是链接器中可能存在的错误。
首先,请参阅 this answer elsewhere并确保包含您的库的项目正在使用 -all_load 链接器标志。
其次,在我使用用于 iPhone 的 Three20 库的一些交易中,也有必要使用这种奇怪的“hack”,例如,如果您的 NSString 类别是 .m 文件中唯一的东西它在哪里实现。
//CategoryBugHack.h
#define FIX_CATEGORY_BUG(name) @interface FIX_CATEGORY_BUG##name @end @implementation FIX_CATEGORY_BUG##name @end
然后是类别 .h/.m ...
//NSStringCategory.h
@interface NSString (MyAdditions)
// etc, etc
@end
//NSStringCategory.m
#import "CategoryBugHack.h"
FIX_CATEGORY_BUG(NSString_MyAdditions)
@implementation NSString (MyAdditions)
// etc, etc
@end
基本上似乎还有一个与静态库相关的额外问题,其中实现文件仅包含类别方法的实现。 FIX_CATEGORY_BUG 宏基本上只是扩展以定义一个接口(interface)和该接口(interface)的实现,没有任何方法,只是为了将一些不是类别的东西强加到 .m 文件中。
关于objective-c - 在子项目中配置条件代码,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/3579165/
|