我注意到了对XCode(4.6)的最新更新,我收到了关于JSONKit.m
中几行的警告。特别是,设置对象类的行:
dictionary->isa = _JKDictionaryClass;
这些标记为已弃用,并注明首选方法是使用object_setClass()
:
object_setClass(dictionary, _JKDictionaryClass);
当我问为什么最好只是让警告静音时,回答是:
即使新的Xcode版本抱怨,一切正常,我不想:
的json文件
1)测试每个项目,我使用JSONKit来检查object_setClass()之后是否一切正常 2)松散的cpu周期,这就是为什么我使用JSONKit而不是NSJSONSerialization的原因。我当前的应用程序解析权重为600K-1M
我们在这里讨论了多少性能影响?
注意:
我对
更感兴趣 dictionary->isa = _JKDictionaryClass
vs object_setClass()
比JSONKit
vs NSJSONSerialization
。
答案 0 :(得分:10)
这个推理与性能打击无关,而且从来没有。具有isa
指针的对象的定义是一个实现细节,并且至少从Objective-C 2.0开始(并且在概念上已经持续了很长时间)。 Clang编译器人员和Apple,特别是参与优化运行时的人员,除了能够将对象定义为具有最快的内部结构而不是始终维护此isa
字段之外,没有比这更好的了。 isa
存在的事实,它存在于每个对象的开头,而isa
只是一个Class
指针的事实,理论上一直在变化。它没有改变到这一点,因为兼容性中断这样做会导致其他任何因素。
此外,object_setClass
与object->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]
一样简单,在计算上更昂贵。