【发布时间】:2012-09-20 08:32:48
【问题描述】:
我正在将一些 Objective-C 代码转换为大量使用 GCC "Statements and Declarations in Expressions" extension ({}) 的 ARC。
GCC 扩展在预处理器宏中用于创建 Objective-C 对象。实际的宏相当复杂,所以这里是一个人为的例子来简化事情。在我的示例中假设_x 参数始终为NSString *:
#define f(_x) ({ NSString *x = (_x); [NSString stringWithString: x]; })
这个宏当然会这样调用:
void foo() { NSString *s = f(@"foo"); }
在 ARC 之前的环境中,这可以正常工作。 stringWithString: 调用创建的对象是自动释放的对象,GCC 扩展将其分配给 s。
在转换为 ARC (Xcode 4.4.1) 之后,当语句块退出时,对象会立即释放(我通过实例化 NSLog()s 它是 dealloc 的对象来确认这一点。
我尝试使用以下类型转换修改宏:
#define f(_x) ({ NSString *x = (_x); (__autoreleasing id) [NSString stringWithString: x]; })
和
#define f(_x) ({ NSString *x = (_x); (NSString __autoreleasing *) [NSString stringWithString: x]; })
但两种形式都会导致编译错误:
Explicit ownership qualifier on cast has no effect
那么看来 ARC 和这个 GCC 扩展是不兼容的。
是这样还是我错过了告诉 ARC 不要立即释放对象的简单内容?
我确实有一些选择,目前最吸引人的似乎是将所有这些宏转换为__inline__ 函数,但我有很多代码要处理。我真的希望能快速修复,因此任何想法都会受到赞赏。
【问题讨论】:
-
坦率地说,我会硬着头皮把它们改成函数,这就是为什么它们一直应该是。
标签: objective-c gcc macros c-preprocessor automatic-ref-counting