object_setClass()的性能而不是指定isa指针

时间:2013-02-20 17:33:23

标签: ios objective-c objective-c-runtime jsonkit

我注意到了对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 vs object_setClass()

JSONKit vs NSJSONSerialization

2 个答案:

答案 0 :(得分:10)

这个推理与性能打击无关,而且从来没有。具有isa指针的对象的定义是一个实现细节,并且至少从Objective-C 2.0开始(并且在概念上已经持续了很长时间)。 Clang编译器人员和Apple,特别是参与优化运行时的人员,除了能够将对象定义为具有最快的内部结构而不是始终维护此isa字段之外,没有比这更好的了。 isa存在的事实,它存在于每个对象的开头,而isa只是一个Class指针的事实,理论上一直在变化。它没有改变到这一点,因为兼容性中断这样做会导致其他任何因素。

此外,object_setClassobject->isa = blah的性能特征有点儿玩笑。在硬件级别,CPU可能会在函数调用影响代码之前很久就优化函数调用的开销。如果您担心pushq %rbp; movq %rsp, %rbp; movq %rsi, (%rdi); popq %rbp; ret中涉及的周期数,那么您不再处于Objective-C问题域中 - 如果您的代码对代码敏感,那么您应该已经在C或汇编语言级别工作了不同的五条指示。

除了所有这些之外,没有什么充分的理由可以开始以这种方式设置对象的类。你为什么要这样做,这对你有什么帮助?

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

编辑:有人向我指出,问题不在于警告本身的原因,而在于相关功能的特定性能特征。正如我在回答中提到的,性能影响非常小,如果它与您的代码相关,那么您首先不应该使用Objective-C。我对误解原始问题表示歉意。

答案 1 :(得分:3)

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