2

我注意到在 XCode (4.6) 的最新更新中,我收到了关于JSONKit.m. 具体来说,设置对象类的行:

dictionary->isa = _JKDictionaryClass;

这些被标记为已弃用,并注明首选方法是使用object_setClass()

object_setClass(dictionary, _JKDictionaryClass);

当我问为什么宁愿简单地使警告静音时,回答是:

即使新的 Xcode 版本抱怨,一切正常,我不想:
1)测试我使用 JSONKit 的每个项目,以检查 object_setClass()之后是否一切正常
2)松散的 cpu 周期,这就是我使用 JSONKit 的原因例如,通过 NSJSONSerialization。我当前的应用程序解析重量为 600K-1M 的 json 文件

我们在这里谈论的性能影响有多大?

注意

我更感兴趣

dictionary->isa = _JKDictionaryClass对比object_setClass()

JSONKitvs NSJSONSerialization

4

2 回答 2

10

推理与性能下降无关,从来没有。将对象定义为具有isa指针是一个实现细节,并且至少从 Objective-C 2.0 开始就一直如此(并且在概念上已经存在了更长的时间)。Clang 编译器人员和 Apple,尤其是参与优化运行时的人员,希望能够将对象定义为具有最快的内部结构,而不是始终维护该isa字段。存在的事实isa,它存在于每个对象的开头,并且isa只是一个Class指针的事实,在理论上总是会发生变化。到目前为止,它并没有改变更多,因为这样做会导致兼容性中断。

此外,object_setClassvs的性能特征object->isa = blah有点开玩笑。CPU 很容易在硬件级别上优化函数调用的开销,而它会影响您的代码。如果您担心所涉及的周期数pushq %rbp; movq %rsp, %rbp; movq %rsi, (%rdi); popq %rbp; ret,那么您不再处于 Objective-C 问题域中 - 如果您的代码对由五个指令产生的不同指令敏感,那么您应该已经在 C 或汇编语言级别工作.

甚至除了所有这些,一开始就以这种方式设置对象的类几乎没有什么充分的理由。你到底为什么要这样做,它对你有什么帮助?

最后,我可能会补充一点,Clang 团队有更好的事情要做,而不是纯粹为了处理这种“性能”“问题”而添加警告。几乎所有警告(不是全部,而是大多数)都意味着您做错了什么,即使它在您正在测试的情况下恰好起作用。对于使用标记指针的任何对象,此代码已经中断。就是 Xcode 试图告诉你的。

编辑:有人向我指出,问题不在于警告本身的原因,而在于所讨论函数的特定性能特征。正如我在回答中提到的,性能损失是如此之小,以至于如果它与您的代码相关,那么您首先不应该使用 Objective-C。我很抱歉误解了原来的问题。

于 2013-02-20T19:38:27.150 回答
3

原因是函数调用总是有一些开销:参数应该被压入堆栈(以及调用者保存的寄存器),然后应该更新指令指针,然后所有这些都应该在函数返回时反向完成。它通常比简单地取消引用指针(它可以像mov [dest] [src].

于 2013-02-20T18:10:56.180 回答