xcode 我如何知道编译器是否启用了 ARC 支持?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9462372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I know whether the compiler has ARC support enabled?
提问by vietstone
I need to write a lib in my iOS app.
我需要在我的 iOS 应用程序中编写一个库。
The statement should be pre-process define as :
该语句应该是预处理定义为:
myObject ...
#if ARC
// do nothing
#else
[myObject release]
#endif
or run-time process as:
或运行时进程为:
if (ARC) {
// do nothing
} else {
[myObject release];
}
How can I do?
我能怎么做?
Please help me! Thank you.
请帮我!谢谢你。
回答by justin
You can use __has_feature
, like so:
你可以使用__has_feature
,像这样:
#if __has_feature(objc_arc)
// ARC is On
#else
// ARC is Off
#endif
If you want to also build with GCC (Apple's GCC does not support ARC), you may also need the following to determine the compiler:
如果您还想使用 GCC 构建(Apple 的 GCC 不支持 ARC),您可能还需要以下内容来确定编译器:
#if defined(__clang)
// It's Clang
#else
// It's GCC
#endif
Update
更新
Combined, they would take the general form:
结合起来,它们将采用一般形式:
#if defined(__clang)
#if !defined(__has_feature)
// idk when clang introduced this
#error This version of clang does not support __has_feature
#endif
#define MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION __has_feature(objc_arc)
#else
// for every compiler other than clang:
#if defined(__has_feature)
#error Another compiler supports __has_feature
#endif
#define MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION 0
#endif
Then just use MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION
in your sources or for further #define
s.
然后只需MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION
在您的来源或进一步的#define
s 中使用。
If a compiler you use adds support, you would have to add a case for that (and compiler errors would likely catch the error in this case, since it would likely forbid use of ref count ops).
如果您使用的编译器添加了支持,则必须为此添加一个案例(并且编译器错误可能会在这种情况下捕获错误,因为它可能会禁止使用引用计数操作)。
Note that this has extra checks to demonstrate how one can (and should) avoid defining reserved identifiers (based on a conversation in the comments). It's not exhaustive, but a demonstration. If you find yourself writing conditional __has_feature
checks often, you may want to define a new macro for that to reduce and simplify definitions.
请注意,这有额外的检查来演示如何(并且应该)避免定义保留标识符(基于评论中的对话)。这不是详尽无遗的,而是一个演示。如果您发现自己__has_feature
经常编写条件检查,则可能需要为此定义一个新宏以减少和简化定义。
回答by tarmes
You can do it using macros:
您可以使用宏来做到这一点:
#if !defined(__clang__) || __clang_major__ < 3
#ifndef __bridge
#define __bridge
#endif
#ifndef __bridge_retain
#define __bridge_retain
#endif
#ifndef __bridge_retained
#define __bridge_retained
#endif
#ifndef __autoreleasing
#define __autoreleasing
#endif
#ifndef __strong
#define __strong
#endif
#ifndef __unsafe_unretained
#define __unsafe_unretained
#endif
#ifndef __weak
#define __weak
#endif
#endif
#if __has_feature(objc_arc)
#define SAFE_ARC_PROP_RETAIN strong
#define SAFE_ARC_RETAIN(x) (x)
#define SAFE_ARC_RELEASE(x)
#define SAFE_ARC_AUTORELEASE(x) (x)
#define SAFE_ARC_BLOCK_COPY(x) (x)
#define SAFE_ARC_BLOCK_RELEASE(x)
#define SAFE_ARC_SUPER_DEALLOC()
#define SAFE_ARC_AUTORELEASE_POOL_START() @autoreleasepool {
#define SAFE_ARC_AUTORELEASE_POOL_END() }
#else
#define SAFE_ARC_PROP_RETAIN retain
#define SAFE_ARC_RETAIN(x) ([(x) retain])
#define SAFE_ARC_RELEASE(x) ([(x) release])
#define SAFE_ARC_AUTORELEASE(x) ([(x) autorelease])
#define SAFE_ARC_BLOCK_COPY(x) (Block_copy(x))
#define SAFE_ARC_BLOCK_RELEASE(x) (Block_release(x))
#define SAFE_ARC_SUPER_DEALLOC() ([super dealloc])
#define SAFE_ARC_AUTORELEASE_POOL_START() NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
#define SAFE_ARC_AUTORELEASE_POOL_END() [pool release];
#endif
The above came from the site: http://raptureinvenice.com/arc-support-without-branches/; but I've pasted it to ensure it's not lost.
以上来自网站:http: //raptureinvenice.com/arc-support-without-branches/;但我已经粘贴了它以确保它不会丢失。
回答by zoul
You generally do not want to do things like this:
你通常不想做这样的事情:
#if ARC
// do nothing
#else
[myObject release]
#endif
Because it's a recipe for disaster, there are many subtle bugs lurking in such code. But if you do have a sane use case for that, you would perhaps be better off with a macro (I didn't know __has_feature
, thanks Justin!):
因为它是灾难的秘诀,所以在这样的代码中潜伏着许多微妙的错误。但是,如果您确实有一个合理的用例,那么使用宏可能会更好(我不知道__has_feature
,谢谢贾斯汀!):
#if __has_feature(objc_arc)
#define MY_RELEASE(x) while (0) {}
#else
#define MY_RELEASE(x) [x release]
#endif
But I would be quite nervous to use even this, the pain potential is huge :)
但即使使用这个我也会很紧张,潜在的痛苦是巨大的:)