我如何知道编译器是否启用了ARC支持?

时间:2022-12-24 07:31:13

I need to write a lib in my iOS app.

我需要在我的iOS应用程序中编写一个lib。

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.

请帮帮我!谢谢。

3 个解决方案

#1


28  

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 #defines.

然后在源中使用MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION或进一步使用#defines。

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).

如果您使用的编译器添加了支持,则必须为此添加一个案例(在这种情况下编译器错误可能会捕获错误,因为它可能禁止使用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检查,则可能需要为此定义新宏以减少和简化定义。

#2


9  

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/;但我已粘贴它以确保它不会丢失。

#3


2  

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 :)

但即使这样使用我也会非常紧张,疼痛的可能性很大:)

#1


28  

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 #defines.

然后在源中使用MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION或进一步使用#defines。

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).

如果您使用的编译器添加了支持,则必须为此添加一个案例(在这种情况下编译器错误可能会捕获错误,因为它可能禁止使用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检查,则可能需要为此定义新宏以减少和简化定义。

#2


9  

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/;但我已粘贴它以确保它不会丢失。

#3


2  

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 :)

但即使这样使用我也会非常紧张,疼痛的可能性很大:)