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

发布于 2024-09-16 01:06:17 字数 528 浏览 6 评论 0原文

根据 Objective-C 运行时参考

ivar_getOffset 返回偏移量 实例变量。

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

在runtime.h中声明

这是为什么呢? object_getIvar 对对象类型有什么作用?

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

According the Objective-C runtime reference:

ivar_getOffset
Returns the offset of
an instance variable.

ptrdiff_t ivar_getOffset(Ivar ivar)
Discussion For instance variables of
type id or other object types, call
object_getIvar and object_setIvar
instead of using this offset to access
the instance variable data directly.

Declared In runtime.h

Why is this? What does object_getIvar do to object types?

EDIT: changed question from subscripting (void *) to (id *).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

已下线请稍等 2024-09-23 01:06:17

在获取 ivar 的值时,这两种方法没有区别。您可以通过查看 Apple 开源 Obj-C 运行时代码

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

将来可能会为这些功能添加更多魔力;一般来说,您应该在任何给定时间使用可用的最高级别的 API。

There is no difference between those two approaches when it comes to getting the value of the ivar. You can verify this by looking at object_getIvar()'s implementation in Apple's open-source Obj-C runtime code.

object_setIvar() does more than just assign to an offset from the object pointer. It is careful to call through to the garbage-collection runtime function objc_assign_ivar() to perform the actual assignment.

More magic might be added to either of these functions in future; in general, you should use the highest-level API available at any given time.

给不了的爱 2024-09-23 01:06:17

也许并不是 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 * 代替。

Perhaps it's not that object_getIvar does something different, but that instance variables of type id or other object types are commonplace, and that calling ivar_getOffset and appending the result to the value of object and then casting to the appropriate type is much more cumbersome.

Note that you cannot reliably increment the value of a void *, based on the following information from the C99 standard (emphasis mine):

C99 §6.2.5 (1): (...) Types are partitioned into object types (types that fully describe objects), function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).

C99 §6.2.5 (19): The void type comprises an empty set of values; it is an incomplete type that cannot be completed.

C99 §6.5.6 (2): For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)

C99 §6.5.2.1 (1): One of the expressions shall have type “pointer to object type”, the other expression shall have integer type, and the result has type “type”.

To increment a pointer by an arbitrary number, you can use char * instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文