我需要在我的iOS应用程序中编写一个lib。
该陈述应该预处理定义为:
myObject ...
#if ARC
// do nothing
#else
[myObject release]
#endif
或运行时进程为:
if (ARC) {
// do nothing
} else {
[myObject release];
}
我该怎么办?
请帮帮我!谢谢。
答案 0 :(得分:28)
您可以使用__has_feature
,如下所示:
#if __has_feature(objc_arc)
// ARC is On
#else
// ARC is Off
#endif
如果您还想使用GCC构建(Apple的GCC不支持ARC),您可能还需要以下内容来确定编译器:
#if defined(__clang)
// It's Clang
#else
// It's 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
。
如果您使用的编译器添加了支持,则必须为此添加一个案例(在这种情况下,编译器错误可能会捕获错误,因为它可能禁止使用ref count ops。)
请注意,这有额外的检查来演示如何(并且应该)避免定义保留标识符(基于评论中的对话)。它并非详尽无遗,而是示范。如果您发现自己经常编写条件__has_feature
检查,则可能需要为此定义一个新宏以减少和简化定义。
答案 1 :(得分:9)
您可以使用宏来执行此操作:
#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/;但我已粘贴它以确保它不会丢失。
答案 2 :(得分:2)
你通常不想做这样的事情:
#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
但即便如此,我也会非常紧张,痛苦的可能性很大:)