为某些文件禁用自动引用计数

183

我已经下载了iOS 5 SDK,发现ARC是新的苹果编译器的一个很好的功能。然而目前为止,许多第三方框架都不支持ARC。我能否对我的新代码使用ARC,并保持当前的retain/release代码不变?由于一些框架(如JSONKit)无法通过转换器转换为ARC,因此ARC转换器在这里不起作用。

编辑:

解决方法是为不想使用ARC的文件添加 -fno-objc-arc 到编译器标志中。在Xcode 4中,您可以在目标-> 构建阶段-> 编译源代码下完成这项操作。


10
ARC的文档在LLVM网站上是公开的。 - Peter Hosey
2
澄清一下,您只需将其添加到“.m”文件中,而不是“.h”文件中。 - ma11hew28
我发现了这个对话: https://github.com/gowalla/AFNetworking/issues/36 也许它能帮助一些人如何在iOS5 ARC支持的项目中集成JSONKit;-) 但是我目前还没有尝试过... - user998652
这个方法对我有效。我正在将AsyncUdpSocket添加到我的项目中,以便进行UDP组播。但是,这些文件(至少当前版本)不支持ARC。因此,我使用上面的方法向AsyncUdpSocket.m文件添加编译器标志,并且我可以让代码与我的应用程序正常工作。 - Ashu Joshi
2
这个完美运行!具体操作:进入你的目标文件,选择Build Phases,然后选择Compile Sources。如果你双击相关的.m文件,它会弹出一个框,你可以在里面输入/粘贴:“-fno-objc-arc”。 - mpemburn
4个回答

78

禁用多个文件的 ARC (自动引用计数),并不是很直观,我曾经一个个地禁用,直到我发现了如何批量操作。

  1. 在 Xcode 的 Target/Build Phases/Compile Sources 中选择所需的文件(CMD+click 或 Shift+click)
  2. 按下 Enter 键(双击将重置选择,因此不起作用)
  3. 键入-fno-objc-arc
  4. 按下 Enter 键或 Done 按钮

1
这并不是对此处提出的问题的答案,但无论如何都是一个非常好的提示!投了+1票。 - Kristof Van Landschoot
你说得对,确实不是,但我总是在谷歌上搜索开关,这个答案排在前几位。我以为现在大多数人都知道答案了,但是不知道这个“窍门”。 - Tibidabo

73

公开的ARC文档虽然没有直接明确这一点,但似乎建议只要每个类都是全ARC或全手动管理,就可以将这些类集成到一个单一的程序中。

您只能在单个类中不能混合ARC和非ARC; 该文档指出,在ARC代码中禁止发送retainreleaseautoreleaseretainCount消息,任何方式都不行(包括使用@selector的定时器和延迟执行)。因此,您不能在ARC类中使用非ARC(因为必要的消息被禁止),也不能在非ARC类中使用ARC(因为ARC添加了无效的语法元素)。

同一文档对于是否可以将非ARC库/框架集成到ARC程序中更加清晰:可以。它没有提到您是否可以在所有代码都是非ARC的程序中使用ARC库/框架,但鉴于以上所有内容,暗示是可以的。


谢谢!我已经找到了如何为现有的非ARC类禁用ARC的方法。 - nonamelive
你能和我们分享一下你在做什么吗? - David H
1
@David H:如果你是想回答问题者,你应该注意到问题者已经编辑了他们的解决方案到问题中。 - Peter Hosey
ARC(自动引用计数)编译无法在头文件中禁用。Clang不会根据其实现/方法文件的编译来编译接口/头文件。因此,头文件必须在混合编译中同时与ARC和非ARC兼容。我认为这是编译器中的错误。 - carmin
1
@carmin:不是这样的。编译器在除了通过从模块文件中#import它们之外,不会查看头文件。编译器标志设置是针对每个模块文件(更准确地说,是“编译源”构建阶段中的每个文件)。编译器无法知道是否应该为任何其他文件使用ARC,除非继承了它开始使用的模块文件的选择。 - Peter Hosey

35

如果您想禁用某些文件的自动引用计数,则非常简单,只需按照以下步骤操作。您可以在Targets -> Build Phases -> Compile Sources中添加编译器标志。

xcode

使用的标志是-fno-objc-arc,输入后按回车键!您需要双击“编译器标志”下的行右侧列。

希望能帮到您,谢谢 :)


14
你可以使用 -fobjc-arc 标志来在非 ARC 项目中对特定文件启用 ARC,方法与之前相同。 - lnafziger
ARC编译无法在头文件中禁用。Clang不会根据其实现/方法文件的编译来编译接口/头文件。因此,在混合编译中,头文件必须同时与ARC和非ARC兼容。我认为这是编译器中的一个错误。 - carmin

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接