菜鸟教程小白 发表于 2022-12-13 05:47:50

objective-c - 在子项目中配置条件代码


                                            <p><p>我有一个项目,它有一个库子项目,可以导入。我可以访问主项目和子项目的源代码。</p>

<p>子项目使用核心文本。由于子项目必须在 3.2 前后的应用程序上使用,Core Text 是弱链接的,所有与 Core Text 相关的代码都包含在逻辑中:</p>

<pre><code>#if defined(__CORETEXT__) &amp;&amp; __IPHONE_OS_VERSION_MAX_ALLOWED &gt;= __IPHONE_3_2
</code></pre>

<p>这行代码的想法是,如果CoreText没有链接进去,代码就跳过了。如果 iPhone 版本低于 3.2; CoreText 未链接。</p>

<p>这个目标的原因是主要项目(并且有几个)并不都使用Core Text,如果不使用则没有'defined(<strong>CoreTEXT</strong>)' ,它们不会编译。</p>

<p>这<em>似乎</em>工作正常,并且在使用 Core Text 的项目上一切编译都没有错误。但是在执行时,找不到代码,并且运行时错误类似于“NSString 不响应 XXXX”(部分代码是 <code>NSString</code> 上的一个类别)。</p>

<p>有人遇到过这种情况吗?我的问题(由于是客户工作而部分含糊不清)是否清楚?</p>

<p>理想情况下,我想这样设置,以便在主项目使用 Core Text 时不需要更改子项目。</p>

<p>请注意,<code>__CORETEXT__</code> 是在 Core Text 框架的 header 中定义的。</p>

<h2>更新问题</h2>

<p>我已经尝试了迄今为止提供的建议,但它们都无效。也许更多的代码将有助于概述问题。我有一个带有以下标题的类别:</p>

<pre><code>@interface NSString (Internal)

- (NSString *)stringByUnescapingEntities;
- (NSString *)flattenHTML;
- (NSString *)flattenHTMLAndParseParagraphBreaks:(BOOL)parseBreaks;
- (NSString *)stringByEscapingForURL;
- (NSString *)stringByEscapingForJSON;

#if defined(__CORETEXT__) &amp;&amp; __IPHONE_OS_VERSION_MAX_ALLOWED &gt;= __IPHONE_3_2
- (CFAttributedStringRef)attributedStringFromHTML;
- (CFAttributedStringRef)attributedStringFromHTMLWithBaseAttributes:(NSDictionary*)baseAttributes;
#endif

@end
</code></pre>

<h3>阳性测试</h3>

<p><code>#if</code>block 之外的所有方法都可以完美运行。 <code>#if</code> <strong>compile</strong> 中的所有方法都完美无缺,没有警告。 </p>

<h3>阴性测试</h3>

<p>如果我将 <code>__CORETEXT__</code> 更改为类似 <code>__THIS_IS_NOT_REAL__</code> 的内容,我将收到 block 内方法的编译错误。因此,至少在编译时,我知道 <code>__CORETEXT__</code> 标志已定义且功能齐全。</p>

<h3>运行时问题</h3>

<p>但是,当我访问在 #ifblock 内声明的方法之一时,我在运行时收到以下错误:</p>

<blockquote>
<p>-: unrecognized selector sent to instance 0x689c000</p>
</blockquote>

<p>实例 <code>0x689c000</code> 是一个 <code>NSString</code>。</p>

<p>如果我删除 <code>__CORETEXT__</code> 逻辑检查,那么只要主项目使用 Core Text,一切都会正常工作。如果主项目未使用 Core Text,则会出现有关缺少链接器的编译错误。</p>

<p>希望能澄清问题。</p>

<p><strong>注意:</strong>所有项目都使用 <code>-all_load</code> 标志;因为 <code>TouchXML</code> 已经需要它了。</p>

<p>我创建了一个演示该问题的测试项目。</p>

<p> <a href="http://zds.s3.amazonaws.com/CTTest.zip" rel="noreferrer noopener nofollow">Test Project</a> </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您指出至少有一个最终丢失的东西是 NSString 的类别方法这一事实使我认为您遇到了一个可爱的问题,这似乎是链接器中可能存在的错误。</p>

<p>首先,请参阅 <a href="https://stackoverflow.com/questions/2906147/what-does-the-all-load-linker-flag-does/2906210#2906210" rel="noreferrer noopener nofollow">this answer elsewhere</a>并确保包含您的库的项目正在使用 -all_load 链接器标志。</p>

<p>其次,在我使用用于 iPhone 的 Three20 库的一些交易中,也有必要使用这种奇怪的“hack”,例如,如果您的 NSString 类别是 .m 文件中唯一的东西它在哪里实现。</p>

<pre><code>//CategoryBugHack.h
#define FIX_CATEGORY_BUG(name) @interface FIX_CATEGORY_BUG##name @end @implementation FIX_CATEGORY_BUG##name @end
</code></pre>

<p>然后是类别 .h/.m ...</p>

<pre><code>//NSStringCategory.h
@interface NSString (MyAdditions)
// etc, etc
@end

//NSStringCategory.m
#import &#34;CategoryBugHack.h&#34;
FIX_CATEGORY_BUG(NSString_MyAdditions)
@implementation NSString (MyAdditions)
// etc, etc
@end
</code></pre>

<p>基本上似乎还有一个与静态库相关的额外问题,其中实现文件仅包含类别方法的实现。 FIX_CATEGORY_BUG 宏基本上只是扩展以定义一个接口(interface)和该接口(interface)的实现,没有任何方法,只是为了将一些不是类别的东西强加到 .m 文件中。</p></p>
                                   
                                                <p style="font-size: 20px;">关于objective-c - 在子项目中配置条件代码,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/3579165/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/3579165/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: objective-c - 在子项目中配置条件代码