views:

636

answers:

3

I have an object that has several properties. If I have a pointer to one of those properties, is it possible to get a pointer to the class instance to which that ivar belongs?

for example: foo.bar, where I know the address of bar, can the address of foo be found?

This seems related to: run time references but I didn't see any references that were quite what I'm looking for.

Thanks for your help!

+1  A: 

Unless the object has a pointer back to it's "parent" or you explicitly track it yourself, I don't believe there's a way to resolve that. You'd really have to trace through memory to find what basically amounts to "who points to me". It's essentially the same problem as finding the previous node in a singly-linked list — you have to start from the beginning and stop when you reach the node that points to the node of interest.

The problem with trying to track down foo from the address to bar is that foo.bar is a pointer that contains the address of an object, and only foo calls it "bar". For simplicity's sake, imagine that foo is at address 0x1000, and foo.bar is at 0x1008 and points to another object at 0x2000. Now, if you have the address 0x2000, there's no easy way to know that 0x1008 points to it.

It's even more complicated if you imagine that N other addresses might also point to 0x2000, so even if you did scan memory, you wouldn't know whether the pointer belonged to an object, struct, local variable, or even was just a random pattern that happened to match the address you're looking for.

Quinn Taylor
+1  A: 

First, you need to adjust your terminology a bit. You cannot have a pointer to a property, because a property is an interface to an object, specifying the format of the getter and setter methods.

If you had a pointer to the getter, a method (IMP) at best you could get back would be a pointer to the class, certainly you could not get back to an instance.

If you had a pointer to an ivar, I don't believe there is any way to get back to the containing object instance. If you had an array of all posible foos, it might be possible to ask each of them for a list of ivars, and get the address of each ivar and eventuallty find the instance in question that way.

The best solution is for bar to contain a parent reference to foo, so that foo.bar.foo will give you the answer you want. But it depends on what exactly you are trying to do. The normal Cocoa way for a lot of these things is to pass foo as well, as is done for many delegates. For example:

[obj foo:foo doSomethingWithBar:foo.bar];
Peter N Lewis
A: 

You could do it if you have a pointer to the instance variable itself, rather than the contents of the instance variable.

Foo * reference = [[Foo alloc] init];
Foo * foo == [[Foo alloc] init];
int * barptr = &(foo->bar);
Foo * baz = (Foo *)((char *)barptr - ((char *)(&(reference->baz)) - (char *)reference));
John Calsbeek