我需要在我的iOS应用程序中编写一个库。
该语句应该预处理定义为:
myObject ...
#if ARC
// do nothing
#else
[myObject release]
#endif
或者作为运行时进程:
if (ARC) {
// do nothing
} else {
[myObject release];
}
我该怎么做?
请帮助我!谢谢。
我需要在我的iOS应用程序中编写一个库。
该语句应该预处理定义为:
myObject ...
#if ARC
// do nothing
#else
[myObject release]
#endif
或者作为运行时进程:
if (ARC) {
// do nothing
} else {
[myObject release];
}
我该怎么做?
请帮助我!谢谢。
你可以使用__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
。
如果你使用的编译器添加了支持,那么你需要为此添加一个case(由于它很可能禁止ref count操作的使用,因此编译器错误很可能会捕获这种情况的错误)。
请注意,这里有额外的检查,以展示如何(也应该如何)避免定义保留标识符(基于评论中的对话)。这并非详尽无遗,但是可以看作是一个演示。如果你发现自己经常编写条件性的__has_feature
检查,你可能想要定义一个新的宏来减少和简化定义。
#define __has_feature(x) 0 //与非clang编译器兼容。
- justin__has_feature
。在苹果系统上,它能够工作是因为CFBase.h定义了它。如果您不直接(或间接)包含CoreFoundation,则结果将是错误的 - 而且点B仍然是一个严重的问题。这里有一个真实世界的实现,支持多个编译器:http://www.boost.org/doc/libs/1_49_0_beta1/boost/type_traits/intrinsics.hpp - justin#define
-- 并使用编译器定义的检查。更新中有说明(上面),也演示了如何检测对 __has_feature
定义的更改。在此不需要定义保留标识符,并且应始终避免这样做。 - justin#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
通常情况下,您不希望做以下这些事情:
#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
但是,我甚至会感到很紧张,即使使用这个功能,疼痛的潜在风险非常大 :)