我有一个具有多个属性的对象。如果我有一个指向这些属性之一的指针,是否可以获得指向该 ivar 所属的类实例的指针?
比如:foo.bar,我知道bar的地址在哪里,能找到foo的地址吗?
这似乎与:运行时引用有关,但我没有看到任何我正在寻找的引用。
谢谢你的帮助!
我有一个具有多个属性的对象。如果我有一个指向这些属性之一的指针,是否可以获得指向该 ivar 所属的类实例的指针?
比如:foo.bar,我知道bar的地址在哪里,能找到foo的地址吗?
这似乎与:运行时引用有关,但我没有看到任何我正在寻找的引用。
谢谢你的帮助!
首先,您需要稍微调整一下您的术语。不能有指向属性的指针,因为属性是对象的接口,指定 getter 和 setter 方法的格式。
如果您有一个指向 getter 的指针,那么您最多可以返回的方法 (IMP) 将是指向该类的指针,当然您无法返回到实例。
如果你有一个指向 ivar 的指针,我不相信有任何方法可以返回到包含的对象实例。如果您有一个包含所有可能 foo 的数组,则可以向它们中的每一个询问 ivars 列表,并获取每个 ivar 的地址,并最终以这种方式找到有问题的实例。
最好的解决方案是让 bar 包含对 foo 的父引用,这样 foo.bar.foo 就会给你想要的答案。但这取决于您到底要做什么。很多这些事情的正常 Cocoa 方法也是传递 foo ,就像许多代表所做的那样。例如:
[obj foo:foo doSomethingWithBar:foo.bar];
除非该对象有一个指向它的“父”的指针,或者您自己明确地跟踪它,否则我不相信有办法解决这个问题。你真的必须通过记忆来找到基本上相当于“谁指向我”的东西。这与在单链表中查找前一个节点本质上是相同的问题——您必须从头开始并在到达指向感兴趣节点的节点时停止。
foo
试图从地址追踪到的问题bar
在于,它foo.bar
是一个包含对象地址的指针,并且只foo
称它为“bar”。为简单起见,假设它foo
位于地址 0x1000,foo.bar
位于 0x1008 并指向位于 0x2000 的另一个对象。现在,如果您有地址 0x2000,则没有简单的方法可以知道 0x1008 指向它。
如果你想象还有 N 个其他地址也可能指向 0x2000,那就更复杂了,所以即使你确实扫描了内存,你也不知道指针是属于一个对象、结构、局部变量,还是只是一个随机模式恰好与您要查找的地址相匹配。
如果你有一个指向实例变量本身的指针,而不是实例变量的内容,你可以这样做。
Foo * reference = [[Foo alloc] init];
Foo * foo == [[Foo alloc] init];
int * barptr = &(foo->bar);
Foo * baz = (Foo *)((char *)barptr - ((char *)(&(reference->baz)) - (char *)reference));