4

Thanks for looking at my question.

I have been trying to look around and I have been playing around with low level IVars to get information from the classes. I am having trouble trying to load the values that come from CGPoint.

CGPoint point;   
object_getInstanceVariable(obj, [columnName UTF8String], (void **)&point);
NSLog(@"%@", NSStringFromCGPoint(point)); 

The output of this should be {220,180}

The i am actually getting {220, 1.72469e-38}

Could anyone help me out and explain why this might be happening?

eaymon
  • 41
  • 1

3 Answers3

1

The real problem here is that a CGPoint is not an object -- it's a plain-old-C struct. :-)

Kaelin Colclasure
  • 3,925
  • 1
  • 26
  • 36
0

Pointers are mixed up here. point is an instance, so &point is a pointer (void *-like), not a pointer to a pointer (void **-like). You need something like this:

CGPoint *point;   
object_getInstanceVariable(obj, [columnName UTF8String], (void **)&point);
NSLog(@"%@", NSStringFromCGPoint(*point)); 
unbeli
  • 29,501
  • 5
  • 55
  • 57
  • CGPoint *point; object_getInstanceVariable(self, [@"annotationLocation" UTF8String],(void **) &point); NSLog(@"%@", NSStringFromCGPoint(*point)); nice try :) that gives me exc_bad_access – eaymon May 31 '10 at 14:41
  • are you sure annotationLocation is a CGPoint field? Also, don't do [@"annotationLocation" UTF8String], just do "annotationLocation" without "@" – unbeli May 31 '10 at 14:45
  • actually there are more issues with that, read better solution here: http://stackoverflow.com/questions/1219081/object-getinstancevariable-works-for-float-int-bool-but-not-for-double – unbeli May 31 '10 at 14:50
  • Thanks.... i looked at that and just tested it but was wondering where the obj param is coming from? Could you let me know? thanks – eaymon May 31 '10 at 16:40
0

object_getInstanceVariable() only copies a pointer-worth of data at the start of the ivar's offset. That's all the storage you give it, after all, with that final void ** argument. When you know you have more than a pointer-worth of data, as in this case, you can use ivar_getOffset() to find where the data starts then copy out as many bytes as you need:

Ivar iv = object_getInstanceVariable(obj, [columnName UTF8String], NULL);
ptrdiff_t offset = ivar_getOffset(iv);
CGPoint point = *(CGPoint *)((char *)obj + offset);

In this case, dereferencing a CGPoint * causes sizeof(CGPoint) bytes to be copied from the referenced address; in the general case, you could memcopy() or bcopy() data from the computed address into an appropriately sized buffer.

The next problem would be computing the correct size at runtime…

Jeremy W. Sherman
  • 35,901
  • 5
  • 77
  • 111