【发布时间】:2012-06-30 10:20:07
【问题描述】:
尽管@ 的重载开始涉足危险领域,但我喜欢在 Clang 3.1 中添加新的 Objective-C 文字。不幸的是,新文字对我的用处有限。除了代码需要与 AppKit 交互的情况外,我大多放弃使用 Foundation 类,转而使用我自己的自定义框架(出于各种原因;其中大部分是我需要直接控制所使用的内存分配模式按对象)。
我总是可以使用一些运行时技巧来将新创建的对象作为我的自定义类传递(这是我已经对字符串对象文字所做的事情,因为只有非 Apple GCC 运行时支持 -fconstantstring=class 标志) , 但这充其量只是一个 hack,并且会抛弃我通过替换等效的 Foundation 类而获得的所有好处。
与字符串对象字面量不同,Clang 实现的新字面量实际上不是常量类(内存布局是硬编码的);相反,适当的消息被发送到它们各自的类,以在运行时创建和初始化一个新对象。效果与您自己创建对象没有什么不同。从理论上讲,这意味着新文字所使用的类和调用的方法不是硬编码的。在实践中,我找不到任何方法将它们更改为指向我自己的自定义类和方法(事实上,我很乐意指向自定义类;在运行时将虚拟方法指向实际方法并不难)。
当我第一次研究这个时,我真的希望找到一组可以用来做我所要求的标志,但由于我没有找到任何标志,我希望有人有一个解决方案。
【问题讨论】:
-
可以使用新语法:mikeash.com/pyblog/…,但是让编译器创建您自己的类的实例可能需要对您的编译器进行破解:aussiebloke.blogspot.com/2012/06/llvm-clang-hacking-part-3.html
-
与其求助于编译器黑客,现在使用宏可能更容易:例如将
MO(@{@"foo":@1})扩展为[MyObject myObjectWithDictionary: @{@"foo":@1} ]。它有点难看,并且会自动释放一个临时对象,但它仍然比旧语法更简洁(也更安全)。 -
@rickster 这可能是我最终要做的;不理想但不是一个糟糕的解决方案。尽管如果预处理器可以处理更广泛的字符集,那将是一个更好的解决方案。然后可以使用
@I(45)、@U(16)或其他同样引人注目的东西。相反,我可能不得不为宏命名,因此很明显它们是文字替换,例如LitInt(45)或LitUInt(16)。 -
这就是为什么将 API/函数/类名称硬编码为一种语言是一种糟糕的做法。 Apple/NeXT/Objective-C 的设计者史诗般的概念、设计和工程失败。
-
@H2CO3 问题是,只有字符串文字被硬编码到 ObjC 中,这是为了在创建它时处理限制。新的硬编码文字得益于 Apple 的推动,我完全同意这是一种糟糕的做法,并将我最喜欢的语言带入了黑暗的领域。我真的希望 Apple 停止尝试隔离开发管道;他们应该尝试让 ObjC 及其框架更加开放,以促进跨平台开发。如果开发人员知道他们可以使用 ObjC 和 Cocoa 并支持所有 PC 平台,那将会带来很多新鲜血液。
标签: objective-c clang objective-c-literals