*(id *)((char *)object + ivar_getOffset(ivar))和object_getIvar(object,ivar)之间有什么区别

时间:2010-08-26 04:33:39

标签: objective-c objective-c-runtime

根据Objective-C runtime reference

  

ivar_getOffset   返回偏移量   实例变量。

     

ptrdiff_t ivar_getOffset(Ivar ivar)   讨论对于实例变量   输入id或其他对象类型,调用   object_getIvar和object_setIvar   而不是使用此偏移量来访问   实例变量数据直接。

     

在runtime.h中声明

这是为什么? object_getIvar对对象类型做了什么?

编辑:将问题从下标(void *)改为(id *)。

2 个答案:

答案 0 :(得分:2)

在获得ivar的价值方面,这两种方法没有区别。您可以通过查看Apple的开源Obj-C runtime code中的object_getIvar()实现来验证这一点。

object_setIvar()不只是分配给对象指针的偏移量。小心地调用垃圾收集运行时函数objc_assign_ivar()来执行实际的赋值。

将来可能会在这些功能中加入更多魔法;通常,您应该在任何给定时间使用最高级别的API。

答案 1 :(得分:1)

也许并不是object_getIvar做了不同的事情,但是类型id或其他对象类型的实例变量是常见的,并且调用ivar_getOffset并将结果附加到值{ object然后转换为适当的类型会更麻烦。

请注意,根据C99标准中的以下信息(强调我的),您无法可靠地增加void *的值:

  

C99§6.2.5(1):( ...)类型被划分为对象类型(完全描述对象的类型),函数类型(类型为描述函数)和不完整类型(描述对象但缺少确定其大小所需信息的类型)。

     

C99§6.2.5(19):void类型包含一组空值; 不完整类型无法完成。

     

C99§6.5.6(2):对于加法,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针,另一个操作数应具有整数类型。 (递增相当于添加1.)

     

C99§6.5.2.1(1):其中一个表达式的类型为“指向对象类型的指针”,另一个表达式应为整数类型,结果的类型为“type”。

要将指针增加任意数字,您可以使用char *代替。