Подтвердить что ты не робот

Как узнать, включен ли в компилятор ARC-поддержка?

Мне нужно написать lib в моем приложении iOS.

Утверждение должно быть определено как:

myObject ...

#if ARC
   // do nothing
#else
   [myObject release]
#endif

или процесс выполнения как:

if (ARC) {
   // do nothing
} else {
   [myObject release];
}

Как я могу это сделать?

Пожалуйста, помогите мне! Спасибо.

4b9b3361

Ответ 1

Вы можете использовать __has_feature, например:

#if __has_feature(objc_arc)
// ARC is On
#else
// ARC is Off
#endif

Если вы хотите также построить с помощью GCC (Apple GCC не поддерживает ARC), для определения компилятора может понадобиться следующее:

#if defined(__clang)
// It Clang
#else
// It GCC
#endif

Обновление

Комбинированные, они будут иметь общий вид:

 #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

Затем просто используйте MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION в своих источниках или для дальнейшего #define s.

Если вы используете компилятор, добавляете поддержку, вам придется добавить к нему случай (и ошибки компилятора, скорее всего, поймут ошибку в этом случае, так как это, скорее всего, запретит использование ref count ops).

Обратите внимание, что у этого есть дополнительные проверки, чтобы продемонстрировать, как можно (и должно) избегать определения зарезервированных идентификаторов (на основе беседы в комментариях). Это не исчерпывающий, а демонстрационный. Если вы обнаружите, что часто выполняете проверку условных __has_feature проверок, вы можете определить новый макрос для этого, чтобы уменьшить и упростить определения.

Ответ 2

Вы можете сделать это с помощью макросов:

#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

Вышеизложенное произошло с сайта: http://raptureinvenice.com/arc-support-without-branches/; но я вставил его, чтобы он не потерялся.

Ответ 3

Обычно вы не хотите делать такие вещи:

#if ARC
   // do nothing
#else
   [myObject release]
#endif

Поскольку его рецепт катастрофы, в этом коде есть много тонких ошибок. Но если у вас есть разумный прецедент для этого, возможно, вам будет лучше с макросом (я не знал __has_feature, спасибо Justin!):

#if __has_feature(objc_arc)
    #define MY_RELEASE(x) while (0) {}
#else
    #define MY_RELEASE(x) [x release]
#endif

Но я бы очень нервничал, чтобы использовать даже это, потенциал боли огромен:)