【问题标题】:What is the difference between *(id *)((char *)object + ivar_getOffset(ivar)) and object_getIvar(object, ivar)*(id *)((char *)object + ivar_getOffset(ivar)) 和 object_getIvar(object, ivar) 有什么区别
【发布时间】:2010-08-26 04:33:38
【问题描述】:
根据Objective-C runtime reference:
ivar_getOffset
返回偏移量
一个实例变量。
ptrdiff_t ivar_getOffset(Ivar ivar)
讨论例如变量
类型 id 或其他对象类型,调用
object_getIvar 和 object_setIvar
而不是使用这个偏移量来访问
直接实例变量数据。
在 runtime.h 中声明
这是为什么? object_getIvar 对对象类型做了什么?
编辑:将问题从下标 (void *) 更改为 (id *)。
【问题讨论】:
标签:
objective-c
objective-c-runtime
【解决方案1】:
在获取 ivar 的值时,这两种方法没有区别。您可以通过查看 Apple 的开源 Obj-C runtime code 中的 object_getIvar() 实现来验证这一点。
object_setIvar() 不仅仅分配给对象指针的偏移量。小心调用垃圾收集运行时函数objc_assign_ivar() 来执行实际分配。
未来可能会为这些功能中的任何一个添加更多魔法;一般来说,您应该使用任何给定时间可用的最高级别 API。
【解决方案2】:
也许不是object_getIvar 做了什么不同的事情,而是id 或其他对象类型的实例变量是司空见惯的,调用ivar_getOffset 并将结果附加到object 的值然后强制转换到合适的类型要麻烦得多。
请注意,根据 C99 标准(强调我的)中的以下信息,您无法可靠地增加 void * 的值:
C99 §6.2.5 (1): (...) 类型分为 object types(完全描述对象的类型)、function types(描述函数)和不完整类型(描述对象但缺乏确定其大小所需信息的类型)。
C99 §6.2.5 (19):void 类型包含一组空值;它是一个不完整类型,无法完成。
C99 §6.5.6 (2):对于加法,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针,而另一个应具有整数类型。 (递增相当于加1。)
C99 §6.5.2.1 (1):其中一个表达式的类型应为“指向对象类型的指针”,另一个表达式应为整数类型,结果为“类型”类型。
要将指针增加任意数字,您可以改用char *。