objective-c - 使用 C 宏创建映射到 Objective-C 消息调用的 C 风格代码?

标签 objective-c c macros

我敢肯定会有 20 个人说“你为什么要这么做”......但是,我还是要问我的问题,因为它在本质上有点学术性。

我想使用 C 宏将 [ClassName new] 重新定义为:new(ClassName),我想知道如何执行此操作。一开始我对 C 宏不太满意(我知道 - 令人尴尬 - 我应该如此) - 我绝对不愿意将它们与我的 Objective-C 代码混合。那么,继续这个问题......

首先,因为它是一个预处理器,我可以做一个像这样的简单替换吗:

#define new(x) [x new]

或者,无论出于何种原因,我是否需要下降到 objective-c 运行时,并做一些更类似于:

#define new(x) objc_msgSend(class_createInstance(x, 0), sel_registerName("init"))

这样做的缺点是什么?

这种东西别人经常用吗,或者,会有人看了说“你他妈在那儿干什么”? (我应该关心)

谢谢

编辑:

在发布这个之后我突然想到,事实上,我以前见过这种事情 - 在 Three20 库中,他们在那里做这样的事情:

#define TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; }
#define TT_INVALIDATE_TIMER(__TIMER) { [__TIMER invalidate]; __TIMER = nil; }

// Release a CoreFoundation object safely.
#define TT_RELEASE_CF_SAFELY(__REF) { if (nil != (__REF)) { CFRelease(__REF); __REF = nil; } }

所以我的问题可能变得简单了;这样做的缺点是什么?它是一种相对公认的做法,还是会让我陷入比它值得的更多麻烦的事情?

最佳答案

首先处理宏,它们是对纯文本源代码进行操作。所以是的,如果您愿意,您可以让您的 new 宏生成 Objective-C 语法或纯 C 语法甚至无效语法。

一般使用宏的缺点是,因为它是在单独的步骤中解析和处理的,所以即使一切看起来都很好,也可能编写出行为不符合您预期的宏。

例如,这个宏:

#define MAX(x,y) x > y ? x : y

看起来不错,但假设你是这样使用它的:

z = MAX(a,MAX(b,c));

它会被预处理器扩展成这样的东西:

z = a > b > c ? b : c ? a : b > c ? b : c;

这实际上不会为您提供三个参数中的最大值。要解决这个问题,您需要在宏定义中随意添加括号,即使您认为不需要括号也是如此:

#define MAX(x,y) ((x) > (y) ? (x) : (y));

这修复了它,除了我在末尾添加了一个分号,这是编写大量 C 代码的一个可以理解的习惯,除了现在我们的宏扩展为:

z = ((a) > (((b) > (c) ? (b) : (c));) ? (a) : (((b) > (c) ? (b) : (c));));;

语法错误!

如果您查看 MAX 在 Objective-C 中的实际定义方式,它会非常困惑,但这是您必须安全地编写宏的方法。您还需要考虑:

z = MAX(expensiveComputation(), reallyExpensiveComputation())

与函数不同,Will 实际上会执行这些函数之一两次,除非您在宏中使用技巧来基本上模拟参数传递。

所以,要回答你的问题,是的,这是完全可能的,但是编写安全的宏真的很难。您这样做是为了假装您的 Objective-C 代码实际上是用另一种语言编写的代码……无论如何,您为什么要这样做?

关于objective-c - 使用 C 宏创建映射到 Objective-C 消息调用的 C 风格代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7934287/

相关文章:

macros - 如何编写 MIT Scheme 宏来返回 lambda 形式?

python - *args, **kwargs 在 jinja2 宏中

c - C 中的宏条件语句

ios - 仪器和泄漏

ios - 停止从右到左语言的 UIImage 翻转

c - 为什么文件读取不输出任何内容?

将十六进制值转换为 C 中字符串类型的 ip 地址。

ios - NSAssert 在调试器中工作,但当直接在设备上运行时,控制台中缺少消息

ios - React-Native:关闭/退出 React-Native View 回到 Native

c++ - 有没有免费的 OCaml 到 C 的翻译器?